文件上传(模板导出批量导入)

Posted 兔年鸿运Q小Q

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文件上传(模板导出批量导入)相关的知识,希望对你有一定的参考价值。

html部分

<b class="addBtn UseraddBtn" style="background: #3d7bde;right: 93px;">+ 批量导入</b>

          <input type="file" id="fileInput"

            style="opacity: 0;right: 93px;width: 88px;height:29px;position: absolute;top:-5px" οnchange="BatchImport()">

          <a href="./模板.xlsx" class="addBtn UseraddBtn" target="_blank"

            style="background-color: #0E9D5F;color: #fff;">导出模板</a>

限制文件上传格式:

1、图片格式    

        accept="image/*"

        仅限制gif png格式   

        accept="image/gif,image/png"

2、excel格式  

        //限制.xls文件
        accept="application/vnd.ms-excel"    
        //限制.xlsx文件
        accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

        同时限制上传.xls、.xlsx文件

        accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel "

        或

        accept=".xls,.xlsx"

js部分 

//批量导入

  function BatchImport()

    var form = new FormData(), fileInput = document.getElementById("fileInput");

    form.append("file", fileInput.files[0]);

    if (!attributeid)

      layer.msg("请先选择导入部门!");

      return;

   

    layer.confirm('您确定要导入该文件吗?',

      btn: ['确定', '取消'] //按钮

    , function ()

      $.ajax(

        url: src + "/api/MailList/InsertPhone?attrid=" + attributeid,

        type: "POST",

        contentType: false,

        processData: false,

        data: form,

        success: function (data)

          if (data)

            layer.msg("导入成功", icon: 1 );

            fileInput.value = "";

            setTimeout(() => loadUserlist(); , 1000);

         

        ,

        error: function (msg)

          console.log(msg)

       

      )

    , function ()

      layer.close(50)

    )

 

js部分限制上传文件类型

if (!['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.ms-excel'].includes(fileInput.files[0].type))

      layer.msg('只能上传.XLS|.XLSX格式的文件!', icon: 2 );

      return;

   

accept接受格式

*.3gpp    audio/3gpp, video/3gpp    3GPP Audio/Video
*.ac3    audio/ac3    AC3 Audio
*.asf    allpication/vnd.ms-asf    Advanced Streaming Format
*.au    audio/basic    AU Audio
*.css    text/css    Cascading Style Sheets
*.csv    text/csv    Comma Separated Values
*.doc    application/msword    MS Word Document
*.dot    application/msword    MS Word Template
*.dtd    application/xml-dtd    Document Type Definition
*.dwg    image/vnd.dwg    AutoCAD Drawing Database
*.dxf    image/vnd.dxf    AutoCAD Drawing Interchange Format
*.gif    image/gif    Graphic Interchange Format
*.htm    text/html    HyperText Markup Language
*.html    text/html    HyperText Markup Language
*.jp2    image/jp2    JPEG-2000
*.jpe    image/jpeg    JPEG
*.jpeg    image/jpeg    JPEG
*.jpg    image/jpeg    JPEG
*.js    text/javascript, application/javascript    JavaScript
*.json    application/json    JavaScript Object Notation
*.mp2    audio/mpeg, video/mpeg    MPEG Audio/Video Stream, Layer II
*.mp3    audio/mpeg    MPEG Audio Stream, Layer III
*.mp4    audio/mp4, video/mp4    MPEG-4 Audio/Video
*.mpeg    video/mpeg    MPEG Video Stream, Layer II
*.mpg    video/mpeg    MPEG Video Stream, Layer II
*.mpp    application/vnd.ms-project    MS Project Project
*.ogg    application/ogg, audio/ogg    Ogg Vorbis
*.pdf    application/pdf    Portable Document Format
*.png    image/png    Portable Network Graphics
*.pot    application/vnd.ms-powerpoint    MS PowerPoint Template
*.pps    application/vnd.ms-powerpoint    MS PowerPoint Slideshow
*.ppt    application/vnd.ms-powerpoint    MS PowerPoint Presentation
*.rtf    application/rtf, text/rtf    Rich Text Format
*.svf    image/vnd.svf    Simple Vector Format
*.tif    image/tiff    Tagged Image Format File
*.tiff    image/tiff    Tagged Image Format File
*.txt    text/plain    Plain Text
*.wdb    application/vnd.ms-works    MS Works Database
*.wps    application/vnd.ms-works    Works Text Document
*.xhtml    application/xhtml+xml    Extensible HyperText Markup Language
*.xlc    application/vnd.ms-excel    MS Excel Chart
*.xlm    application/vnd.ms-excel    MS Excel Macro
*.xls    application/vnd.ms-excel    MS Excel Spreadsheet
*.xlt    application/vnd.ms-excel    MS Excel Template
*.xlw    application/vnd.ms-excel    MS Excel Workspace
*.xml    text/xml, application/xml    Extensible Markup Language
*.zip    aplication/zip    Compressed Archive

完整版excel上传导入读写批量数据并将反馈结果写入远程exel中

思路:excel的读写借助于poi框架,在写入远程的时候,是不能直接写入的,本博主将传入的文件再次拉下来写到项目临时文件中,然后,在临时文件中写入,然后,以同样的名称路径覆盖掉远程的就可以了,稍微有点绕了,从远端获取文件,需要通过流来写到项目临时文件中,具体见下方代码,代码中有部分业务删减,该代码是在工作中运行通过的。模板是我们自己制定的,所以只适合已有模板。

文件工具类及方法:

  1 package com.XXXX.XXXXX.utils;
  2 
  3 import java.io.ByteArrayOutputStream;
  4 import java.io.File;
  5 import java.io.FileInputStream;
  6 import java.io.FileNotFoundException;
  7 import java.io.FileOutputStream;
  8 import java.io.IOException;
  9 import java.io.InputStream;
 10 import java.net.HttpURLConnection;
 11 import java.net.URL;
 12 import java.text.DecimalFormat;
 13 import java.util.ArrayList;
 14 import java.util.List;
 15 
 16 import org.apache.commons.io.FileUtils;
 17 import org.apache.poi.hssf.usermodel.HSSFDateUtil;
 18 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 19 import org.apache.poi.ss.usermodel.Cell;
 20 import org.apache.poi.ss.usermodel.CellType;
 21 import org.apache.poi.ss.usermodel.Row;
 22 import org.apache.poi.ss.usermodel.Sheet;
 23 import org.apache.poi.ss.usermodel.Workbook;
 24 import org.apache.poi.ss.usermodel.WorkbookFactory;
 25 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 26 import org.slf4j.Logger;
 27 import org.slf4j.LoggerFactory;
 28 import org.springframework.util.ResourceUtils;
 29 
 30 import com.sun.javafx.scene.control.skin.TreeTableRowSkin;
 31 import com.topband.cloud.common.utils.DateFormatUtil;
 32 import com.topband.cloud.common.utils.StringUtil;
 33 
 34 public class ReadExcelUtil {
 35     
 36     private static final String EXCEL_XLS = ".xls";
 37     private static final String EXCEL_XLSX = ".xlsx";
 38     
 39     /**
 40      *读取excel数据
 41      * @throws Exception 
 42      *
 43      */
 44     public static List<List<String>> readExcelInfo(String url) throws Exception{
 45 //        支持excel2003、2007
 46         File excelFile = new File(url);//创建excel文件对象
 47         InputStream is = new FileInputStream(excelFile);//创建输入流对象
 48         checkExcelVaild(excelFile);
 49         Workbook workbook = getWorkBook(is, excelFile);
 50 //        Workbook workbook = WorkbookFactory.create(is);//同时支持2003、2007、2010
 51 //        获取Sheet数量
 52         int sheetNum = workbook.getNumberOfSheets();
 53         sheetNum = 1;//限制模板只在一个工作簿上操作
 54 //      创建二维数组保存所有读取到的行列数据,外层存行数据,内层存单元格数据
 55         List<List<String>> dataList = new ArrayList<List<String>>();
 56 //        遍历工作簿中的sheet,第一层循环所有sheet表
 57         for(int index = 0;index<sheetNum;index++){
 58             Sheet sheet = workbook.getSheetAt(index);
 59             if(sheet==null){
 60                 continue;
 61             }
 62 //            如果当前行没有数据跳出循环,第二层循环单sheet表中所有行
 63             for(int rowIndex=0;rowIndex<=sheet.getLastRowNum();rowIndex++){
 64                 System.out.println(sheet.getLastRowNum()+"====");
 65                 Row row = sheet.getRow(rowIndex);
 66                 if(row==null){
 67                     continue;
 68                 }
 69 //                遍历每一行的每一列,第三层循环行中所有单元格
 70                 List<String> cellList = new ArrayList<String>();
 71                 for(int cellIndex=0;cellIndex<row.getLastCellNum();cellIndex++){
 72                     Cell cell = row.getCell(cellIndex);
 73                     System.out.println(cellIndex);
 74                     cellList.add(getCellValue(cell));
 75                 }
 76                 dataList.add(cellList);
 77             }
 78             
 79         }
 80         is.close();
 81         return dataList;
 82         }
 83     /**
 84      *获取单元格的数据,暂时不支持公式
 85      * 
 86      *
 87      */
 88         public static String getCellValue(Cell cell){
 89             CellType cellType = cell.getCellTypeEnum();
 90             if(cellType==null){
 91                 return null;
 92             }
 93             String cellValue = "";
 94             if(cell==null || cell.toString().trim().equals("")){
 95                 return null;
 96             }
 97             
 98             if(cellType==CellType.STRING){
 99                 cellValue = cell.getStringCellValue().trim();
100                 return cellValue = StringUtil.isEmpty(cellValue)?"":cellValue;
101             }
102             if(cellType==CellType.NUMERIC){
103                 if (HSSFDateUtil.isCellDateFormatted(cell)) {  //判断日期类型
104                      cellValue = DateFormatUtil.formatDurationYMD(cell.getDateCellValue().getTime());
105                  } else {  //
106                      cellValue = new DecimalFormat("#.######").format(cell.getNumericCellValue()); 
107                  } 
108                 return cellValue;
109             }
110             if(cellType==CellType.BOOLEAN){
111                 cellValue = String.valueOf(cell.getBooleanCellValue());
112                 return cellValue;
113             }
114             return null;
115             
116         }
117     /**
118      *判断excel的版本,并根据文件流数据获取workbook
119      * @throws IOException 
120      *
121      */
122     public static Workbook getWorkBook(InputStream is,File file) throws Exception{
123         
124         Workbook workbook = null;
125         if(file.getName().endsWith(EXCEL_XLS)){
126             workbook = new HSSFWorkbook(is);
127         }else if(file.getName().endsWith(EXCEL_XLSX)){
128             workbook = new XSSFWorkbook(is);
129         }
130         
131         return workbook;
132     }
133     /**
134      *校验文件是否为excel
135      * @throws Exception 
136      * 
137      *
138      */
139     public static void checkExcelVaild(File file) throws Exception {
140         String message = "该文件是EXCEL文件!";
141         if(!file.exists()){
142             message = "文件不存在!";
143             throw new Exception(message);
144         }
145         if(!file.isFile()||((!file.getName().endsWith(EXCEL_XLS)&&!file.getName().endsWith(EXCEL_XLSX)))){
146             message = "文件不是Excel";
147             throw new Exception(message);
148         }
149     }
150     /**
151      *校验上传的excel模板是否正确
152      * 
153      * 
154      *
155      */
156     public static boolean checkExcelTemplate(String url){
157             try {
158                 List<List<String>> list = ReadExcelUtil.readExcelInfo(url);
159                 for(int i=0;i<list.size();i++){
160                     if(i==0){
161                         if(!list.get(i).get(0).trim().equals("公司ID")||!list.get(i).get(1).trim().equals("产品ID")||!list.get(0).get(2).trim().equals("设备类型")
162                                 ||!list.get(i).get(3).trim().equals("设备型号")||!list.get(i).get(4).trim().equals("设备名称")){
163                             return false;
164                         }
165                     }
166                     if(i==2){
167                         if(!list.get(i).get(0).trim().equals("设备ID")||!list.get(i).get(1).trim().equals("结果")){
168                             return false;
169                         }
170                     }
171             } 
172                 }catch (Exception e) {
173                 // TODO Auto-generated catch block
174                 e.printStackTrace();
175             }
176             return true;
177 
178         }
179     /**
180      * 将反馈结果写入excel中
181      * */
182     public static void writeExcelResult(String url,List<Integer> result) throws Exception{
183 //        支持excel2003、2007
184         File excelFile = new File(url);//创建excel文件对象
185         InputStream is = new FileInputStream(excelFile);//创建输入流对象
186         checkExcelVaild(excelFile);
187         Workbook workbook = getWorkBook(is, excelFile);
188 //        Workbook workbook = WorkbookFactory.create(is);//同时支持2003、2007、2010
189 //        获取Sheet数量
190         int sheetNum = workbook.getNumberOfSheets();
191         sheetNum = 1;//限制模板只在一个工作簿上操作
192 //        遍历工作簿中的sheet,第一层循环所有sheet表
193         for(int index = 0;index<sheetNum;index++){
194             Sheet sheet = workbook.getSheetAt(index);
195             if(sheet==null){
196                 continue;
197             }
198 //            如果当前行没有数据跳出循环,第二层循环单sheet表中所有行
199             for(int rowIndex=3;rowIndex<=sheet.getLastRowNum();rowIndex++){
200                 Row row = sheet.getRow(rowIndex);
201                 row.createCell(1).setCellValue(result.get(rowIndex-3));
202             }
203             
204         }
205         FileOutputStream outputStream = new FileOutputStream(url);
206         workbook.write(outputStream);
207         outputStream.close();
208         }
209       /** 
210      * 根据地址获得客户上传的excel字节流 
211      * @param fileUrl 网络连接地址 
212      * @return 
213      */  
214     public static byte[] getExcelFromAliyun(String fileUrl){  
215         try {  
216             URL url = new URL(fileUrl);  
217             HttpURLConnection conn = (HttpURLConnection)url.openConnection();  
218             conn.setRequestMethod("GET");  
219             conn.setConnectTimeout(5 * 1000);  
220             InputStream inStream = conn.getInputStream();//通过输入流获取excelFile数据  
221             byte[] excelFile = readInputStream(inStream);//得到excelFile的二进制数据  
222             return excelFile;  
223         } catch (Exception e) {  
224             e.printStackTrace();  
225         }  
226         return null;  
227     }  
228     /** 
229      * 从网上得到的输入流中获取数据转换为二进制数据 
230      * @param inStream 输入流 
231      * @return 
232      * @throws Exception 
233      */  
234     public static byte[] readInputStream(InputStream inStream) throws Exception{  
235         ByteArrayOutputStream outStream = new ByteArrayOutputStream();  
236         byte[] buffer = new byte[1024];  
237         int len = 0;  
238         while( (len=inStream.read(buffer)) != -1 ){  
239             outStream.write(buffer, 0, len);  
240         }  
241         inStream.close();  
242         return outStream.toByteArray();  
243     }
244     /** 
245      * 将文件写入到目标目录中 
246      * @param excel 文件数据流
247      * @param fileName 文件保存时的名称 
248      */  
249     public static void writeFileToDest(byte[] excelFile, File dest){  
250         try {  
251             FileOutputStream out = new FileOutputStream(dest);  
252             out.write(excelFile);  
253             out.flush();  
254             out.close();  
255         } catch (Exception e) {  
256             e.printStackTrace();  
257         }  
258     }
259     /***
260      * 
261      * 在项目中创建临时文件
262      * @throws IOException 
263      * */
264     public static File createTempFile(String fileName) throws IOException{
265         File path = new File(ResourceUtils.getURL("classpath:").getPath());
266         if(!path.exists()) path = new File("");
267         File upload = new File(path.getAbsolutePath(),"static/images/upload/");
268         if(!upload.exists()) upload.mkdirs();
269         File tempFile = new File(upload+"/"+fileName);
270         if(!tempFile.getParentFile().exists()){
271             tempFile.getParentFile().mkdirs();//创建父级文件路径
272             tempFile.createNewFile();//创建文件
273         }
274         return tempFile;
275     }
276 }

contrller层代码

  1 @PostMapping("/addBatchDevice")
  2     public ResponseObj addBatchDevice(@RequestBody JSONObject obj) throws IOException{
  3         logger.info("导入批量设备:"+obj.toJSONString());
  4         ResponseObj response = new ResponseObj();
  5         String id = obj.getString("id");
  6         BatchRecord batchRecord = deviceService.selectBatchRecordById(id);
  7         String path = aliConstants.aliyunHostOuter+"/"+batchRecord.getFilePath();
  8 //        将该该文件下载出来保存到项目中
  9         byte[] excelFile = ReadExcelUtil.getExcelFromAliyun(path);
 10         File tempFile = ReadExcelUtil.createTempFile(batchRecord.getFileName());
 11         ReadExcelUtil.writeFileToDest(excelFile, tempFile);
 12         String url = tempFile.getAbsolutePath();
 13         String companyId = null;
 14         String productId = null;
 15         Integer deviceType = null;
 16         String model = null;
 17         String deviceName = null;
 18         boolean flag = ReadExcelUtil.checkExcelTemplate(url);
 19         if(!flag){
 20             response.setData(Defined.STATUS_ERROR);
 21             response.setMessage("文件有误,请根据模板上传文件。");
 22             return response;
 23         }
 24         List<Integer> result = new ArrayList<Integer>();//存放反馈信息 
 25         try {
 26             List<List<String>> list = ReadExcelUtil.readExcelInfo(url);
 27             for(int i=0;i<list.size();i++){
 28             if(i==0||i==2){
 29                 continue;//跳过模板第1,3行
 30             }    
 31             if(i==1){
 32                 companyId = list.get(i).get(0);
 33                 productId = list.get(i).get(1);
 34                 deviceType = Integer.valueOf(list.get(i).get(2));
 35                 model = list.get(i).get(3);
 36                 deviceName = list.get(i).get(4);
 37             }
 38             if(i>2){
 39 //                new一个对象按照相应的字段设置进去就可以了,这里省略对象设置值,字段如下:
 40                 Device device = new Device();
 41                 String deviceId = IdGen.uuid();
 42                 device.setId(deviceId);
 43                 //省略部分业务代码
 44                 DeviceFields deviceFields = new DeviceFields();
 45                 deviceFields.setId(IdGen.uuid());
 46                 deviceFields.setDeviceId(deviceId);
 47                 //省略部分业务代码
 48                 Gateway gateway = new Gateway();
 49                 gateway.setId(IdGen.uuid());
 50                 //省略部分业务代码
 51                 if(!deviceService.checkDeviceUidRepeat(uid)){
 52 //                    重复,返回sheet行号,并写入sheet表单中
 53                     result.add(1);
 54                     continue;
 55                 }
 56 //                关联表一个事务处理
 57                 boolean flg = deviceService.addDeviceEtc(device, deviceFields, gateway);
 58                 if(!flg){
 59                     result.add(1);
 60                 }else{
 61                     result.add(0);
 62                 }
 63             }
 64         }
 65 //            将反馈结果写入文件0-成功,1-失败
 66             ReadExcelUtil.writeExcelResult(url, result);
 67             AliYunFileSetting setting = new AliYunFileSetting();
 68             setting.setAccessKeyId(aliConstants.accessKeyId);
 69             setting.setAccessKeySecret(aliConstants.accessKeySecret);
 70             setting.setBucketName(aliConstants.bucketName);
 71             setting.setEndpoint(aliConstants.endpoint);
 72             AliyunFileManager manager = AliyunFileManager.getInstance(setting);
 73             InputStream is = new FileInputStream(tempFile);
 74             String relativePath =aliConstants.excelFilePath;//相对路径
 75             boolean fg = manager.upload(is, relativePath, batchRecord.getFileName());//上传文件与客户上传后生成的文件名相同。
 76             if(fg){
 77                 logger.info("反馈已经成功写入文件中!");
 78 //            更新批量记录
 79                 batchRecord.setUpdateTime(DateUtil.getNowTimestamp());
 80                 deviceService.updateBatchRecordByPrimaryKey(batchRecord);
 81             }
 82     } catch (Exception e) {
 83             // TODO Auto-generated catch block
 84             e.printStackTrace();
 85         }
 86         response.setMessage("批量导入设备成功!");
 87         response.setStatus(Defined.STATUS_SUCCESS);
 88         return response;
 89     }
 90     @PostMapping("uploadExcel")
 91      public ResponseObj uploadExcel(@RequestParam("excelFile") MultipartFile file,@RequestParam("companyId") String companyId,
 92              @RequestParam("productId") String productId,HttpServletRequest request) throws Exception {
 93         ResponseObj response = new ResponseObj();
 94         response.setData(Defined.STATUS_SUCCESS);
 95         response.setMessage("文件上传成功!");
 96         ResponseObj resp = new ResponseObj();
 97         resp.setData(Defined.STATUS_ERROR);
 98         resp.setMessage("不是文件!");
 99         AliYunFileSetting setting = new AliYunFileSetting();
100         setting.setAccessKeyId(aliConstants.accessKeyId);
101         setting.setAccessKeySecret(aliConstants.accessKeySecret);
102         setting.setBucketName(aliConstants.bucketName);
103         setting.setEndpoint(aliConstants.endpoint);
104         AliyunFileManager manager = AliyunFileManager.getInstance(setting);
105         if(file.isEmpty()){
106             response.setData(Defined.STATUS_ERROR);
107             response.setMessage("不是文件!");
108             return response;
109            }
110         String fileName = file.getOriginalFilename();
111         long fileSize = file.getSize();
112         File tempFile = ReadExcelUtil.createTempFile(fileName);
113         String relativePath =aliConstants.excelFilePath;//相对路径
114         String dir =  aliConstants.aliyunHostOuter+"/"+relativePath;//云端绝对路径
115         File dest = new File(dir);
116         if(!dest.exists()){ //判断文件目录是否存在
117             dest.mkdir();//
118         }
119         try {
120             file.transferTo(tempFile); 
121             InputStream is = new FileInputStream(tempFile);
122             String suffix=fileName.substring(fileName.lastIndexOf("."));//获取原始文件后缀.xlxs(含点)
123             String newFileName = IdGen.uuid()+suffix;
124             boolean result = manager.upload(is, relativePath, newFileName);//上传文件,并建立随机文件名。
125 //          boolean result = manager.upload(is, dir, fileName);//上传阿里云,固定文件名
126             if(result){
127                  response.setData(dir+"/"+newFileName);//返回新建文件名的绝对路径
128 //                 数据库存入相对路径
129                  BatchRecord batchRecord = new BatchRecord();
130                  batchRecord.setFileName(newFileName);
131                  batchRecord.setFilePath(relativePath+"/"+newFileName);
132                  batchRecord.setFileSize(fileSize);
133                  batchRecord.setIsDelete((byte) 0);
134                  batchRecord.setStatus((byte) 0);
135                  batchRecord.setId(IdGen.uuid());
136                  batchRecord.setCreateTime(DateUtil.getNowTimestamp());
137 //                 batchRecord.setUpdateTime(DateUtil.getNowTimestamp());
138                  batchRecord.setCompanyId(companyId);
139                  batchRecord.setProductId(productId);
140                  Integer resultNum  = deviceService.addBatchRecord(batchRecord);
141                  if(resultNum>0){
142                      tempFile.delete();
143                  return response;
144                  }
145                  return resp;
146             }else{
147                 resp.setMessage("文件上传失败!");
148                 return resp;
149             }
150         } catch (IllegalStateException e) {
151             // TODO Auto-generated catch block
152             e.printStackTrace();
153             resp.setMessage("文件上传异常!");
154             return resp;
155         } catch (IOException e) {
156             // TODO Auto-generated catch block
157             e.printStackTrace();
158             resp.setMessage("文件上传异常!");
159             return resp;
160         }
161     }

模板图片:

技术分享图片

 

以上是关于文件上传(模板导出批量导入)的主要内容,如果未能解决你的问题,请参考以下文章

ecshop安装在linux下后台下载商品批量上传模板,生成出的csv文件内容都是乱码,如何修改?

批量导入数据(excel模板文件方式)

excel 导入导出测试点

如何实现Magento产品批量导入

Proxmox VE 7.2 qm 方式批量导入ESXi OVA

Vue导出模板使用前端js办法导出表格数据导入表格前端读取表格数据导入表格发送后端读取数据