springboot的poi导入和导出

首页 / 新闻资讯 / 正文

1.pom.xml

<!--poi.start --> 		<dependency> 			<groupId>org.apache.poi</groupId> 			<artifactId>poi</artifactId> 			<version>${org-apache-poi.version}</version> 		</dependency> 		<dependency> 			<groupId>org.apache.poi</groupId> 			<artifactId>poi-excelant</artifactId> 			<version>${org-apache-poi.version}</version> 		</dependency> 		<dependency> 			<groupId>org.apache.poi</groupId> 			<artifactId>poi-ooxml</artifactId> 			<version>3.15</version> 		</dependency> 	<!--poi.end -->

2.读取工具类

package com.common.utils;  import lombok.Data; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook;  import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;  /**  * 读取excel工具类  */ public class ExcelReadUtils {      private XSSFWorkbook workbook;     private XSSFSheet sheet;      /**      * 工作表下标      */     private int sheetIndex = 0;      public ExcelReadUtils(){}     public ExcelReadUtils(File file) throws IOException {         FileInputStream inputStream = new FileInputStream(file);         this.workbook = new XSSFWorkbook(inputStream);         inputStream.close();          this.changeSheet();     }     public ExcelReadUtils(File file, int sheetIndex) throws IOException {         FileInputStream inputStream = new FileInputStream(file);         this.workbook = new XSSFWorkbook(inputStream);         inputStream.close();          this.sheetIndex = sheetIndex;         this.changeSheet();     }      /**      * 获取某行的单元格的值-字符串数组      * @param rowIndex      * @return      */     public List<String> getRowStrArr(int rowIndex){         List<String> res = new ArrayList<>();         XSSFRow row = this.sheet.getRow(rowIndex);         for (int j = 0; j < row.getLastCellNum(); j++) {             XSSFCell dataCell = row.getCell(j);             String cellValue = this.convertCellValueToString(dataCell);             res.add(cellValue);         }         return res;     }      /**      * 获取某行的单元格的值-根据keyArr列顺序拼接成map      * @param rowIndex      * @param keyArr      * @return      */     public Map<String, String> getRowStrMap(int rowIndex, List<String> keyArr){         List<String> list = this.getRowStrArr(rowIndex);          Map<String, String> res = new HashMap<>();         if( CollectionUtils.isNotEmpty(list) ){             for(int i=0; i<list.size(); i++){                 String key = "column_"+i;                 if(CollectionUtils.isNotEmpty(keyArr) && i<keyArr.size()) {                     key = keyArr.get(i);                 }                 res.put(key, list.get(i));             }         }         return res;     }      /**      * 获取所有行的数据-根据keyArr列顺序拼接成map      * @param keyArr      * @return      */     public List<Map<String, String>> getAllDataMap(List<String> keyArr){         List<Map<String, String>> res = new ArrayList<>();         for (int i = 0; i <= this.sheet.getLastRowNum(); i++) {             Map<String, String> item = this.getRowStrMap(i, keyArr);             res.add(item);         }         return res;     }      /**      * 更换工作表      * @return      */     private void changeSheet(){         this.sheet = this.workbook.getSheetAt(this.sheetIndex);     }      /**      * 将单元格内容转化为字符串      */     private String convertCellValueToString(Cell cell) {         if (null == cell) {             return null;         }         String returnValue = null;         switch (cell.getCellTypeEnum()) {             //字符串             case STRING:                 returnValue = cell.getStringCellValue();                 break;             //数字             case NUMERIC:                 double numericCellValue = cell.getNumericCellValue();                 boolean isInteger = isIntegerForDouble(numericCellValue);                 if (isInteger) {                     DecimalFormat df = new DecimalFormat("0");                     returnValue = df.format(numericCellValue);                 } else {                     returnValue = Double.toString(numericCellValue);                 }                 break;             //布尔             case BOOLEAN:                 boolean booleanCellValue = cell.getBooleanCellValue();                 returnValue = Boolean.toString(booleanCellValue);                 break;             //空值             case BLANK:                 break;             //公式             case FORMULA:                 cell.getCellFormula();                 break;             //故障             case ERROR:                 break;             default:                 break;         }         return returnValue;     }     /**      * 判断是否为整数,是返回true,否则返回false.      */     public static boolean isIntegerForDouble(Double num) {         double eqs = 1e-10; //精度范围         return num - Math.floor(num) < eqs;     }      /**      * 使用完要关闭流      */     public void close() throws IOException {         this.workbook.close();     }      public int getSheetIndex() {         return sheetIndex;     }      public ExcelReadUtils setSheetIndex(int sheetIndex) {         this.sheetIndex = sheetIndex;         this.changeSheet();         return this;     } } 

3.写入工具类

package com.common.utils;  import com.common.exceptions.BaseException; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook;  import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.*;  /**  * 写excel工具类  */ public class ExcelWriteUtils {      private XSSFWorkbook workbook;      private List<XSSFSheet> sheetArr;     private List<String> sheetNameArr;      private int currSheetIndex = 0;     private int currRowIndex = 0;      public ExcelWriteUtils(){         this.sheetNameArr = Arrays.asList("sheet1");         this.initSheetArr();     }     public ExcelWriteUtils(String sheetName) {         this.sheetNameArr = Arrays.asList(sheetName);         this.initSheetArr();     }     public ExcelWriteUtils(List<String> sheetNameArr) {         this.sheetNameArr = sheetNameArr;         this.initSheetArr();     }      /**      * 初始化sheet      * @throws Exception      */     private void initSheetArr() {         if( CollectionUtils.isEmpty(this.sheetNameArr) ){             throw BaseException.logicException("sheet没有设置名称");         }         //XSSFWorkbook:07版本的xlsx         this.workbook = new XSSFWorkbook();         //构造sheet         this.sheetArr = new ArrayList<>();         this.sheetNameArr.forEach(sheetName->{             XSSFSheet sheet = this.workbook.createSheet(sheetName);             this.sheetArr.add(sheet);         });     }      /**      * 获取当前sheet      * @return      */     private XSSFSheet getCurrSheet(){         return this.sheetArr.get(this.currSheetIndex);     }      /**      * 写入数据到某行      * @param valueArr      */     public void writeRow(int rowIndex, List<String> valueArr){         XSSFRow row = this.getCurrSheet().getRow(rowIndex);         if( row==null ){             row = this.getCurrSheet().createRow(rowIndex);         }         if( CollectionUtils.isNotEmpty(valueArr) ){             for(int i=0; i<valueArr.size(); i++){                 XSSFCell cell = row.createCell(i);                 cell.setCellValue(valueArr.get(i));             }         }     }      /**      * 写入数据到当前行      * @param valueArr      */     public void writeCurrRow(List<String> valueArr){         this.writeRow(this.currRowIndex, valueArr);     }      /**      * 批量写入数据到多行      * @param valueArrArr      */     public void writeBatchRow(List<List<String>> valueArrArr){         if( CollectionUtils.isNotEmpty(valueArrArr) ){             valueArrArr.forEach(valueArr->{                 if( CollectionUtils.isNotEmpty(valueArr) ){                     this.writeCurrRow(valueArr);                 }                 this.currRowIndex++;             });         }     }      public int getCurrSheetIndex() {         return currSheetIndex;     }      public void setCurrSheetIndex(int currSheetIndex) {         this.currSheetIndex = currSheetIndex;     }      public int getCurrRowIndex() {         return currRowIndex;     }      public void setCurrRowIndex(int currRowIndex) {         this.currRowIndex = currRowIndex;     }      public XSSFWorkbook getWorkbook() {         return workbook;     } } 

4.测试

上传文件,读取excel内容,log打印,然后生成新的excel,最后下载这个excel文件

4.1 控制器

package com.demo.mydemo.controller;   import com.common.utils.AjaxResult; import com.common.utils.StringUtils; import com.demo.mydemo.entity.dto.ExcelParamDTO; import com.demo.mydemo.service.IExcelService; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody;  import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import java.net.URLEncoder;  /**  * <p>  *  excel  * </p>  *  * @author szy  * @since 2022-05-06  */ @Controller @RequestMapping("/excel") public class ExcelController {      @Autowired     private IExcelService excelService;      /**      *  http://localhost:20001/szy-tools/excel/index      * @return      */     @RequestMapping("/index")     public String index() {         return "excel_index";     }      /**      * http://localhost:20001/szy-tools/excel/upload      */     //限制只能post访问     @RequestMapping(value="/upload", method= RequestMethod.POST)     @ResponseBody     public AjaxResult uploadData(             @ApiParam(value = "参数") ExcelParamDTO param) {         String filePath = excelService.upload(param);         return AjaxResult.success("成功", filePath);     }      @RequestMapping("/download")     @ApiOperation(value = "下载文件")     public void download(             HttpServletResponse response,             @ApiParam(value = "文件路径") @RequestParam(value="filePath", required = true) String filePath     ) throws IOException {         File fileUpload = new File(filePath);         String fileName = fileUpload.getName();         //encode后替换  解决空格问题         fileName = URLEncoder.encode(fileName, "UTF-8");         fileName = fileName.replace("+", "%20");         // 读到流中 //        URL url = new URL(fileUpload.getFileUrl()); //        URLConnection conn = url.openConnection(); //        InputStream inputStream = conn.getInputStream();         InputStream inputStream = new FileInputStream(fileUpload);         response.reset();         response.setContentType("application/octet-stream");         response.addHeader("Content-Disposition", "attachment; filename=" + fileName);         ServletOutputStream outputStream = response.getOutputStream();         byte[] b = new byte[1024];         int len;         //从输入流中读取一定数量的字节,并将其存储在缓冲区字节数组中,读到末尾返回-1         while ((len = inputStream.read(b)) > 0) {             outputStream.write(b, 0, len);         }         inputStream.close();     }  }  

4.2 服务类/业务类

接口类

package com.demo.mydemo.service;   import com.demo.mydemo.entity.dto.ExcelParamDTO; import com.demo.mydemo.entity.dto.SmbParamDTO;  import java.io.File;  public interface IExcelService {      String upload(ExcelParamDTO param); } 

实现类

package com.demo.mydemo.service.impl;  import com.common.exceptions.BaseException; import com.common.utils.*; import com.demo.mydemo.entity.dto.*; import com.demo.mydemo.service.IExcelService; import lombok.extern.slf4j.Slf4j; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.springframework.stereotype.Service; import org.springframework.util.ResourceUtils; import org.springframework.web.multipart.MultipartFile;  import java.io.*; import java.util.*;  import static java.util.regex.Pattern.compile;  @Service @Slf4j public class ExcelServiceImpl implements IExcelService {     @Override     public String upload(ExcelParamDTO param){         File uploadFile = null;         try {             //上传文件             uploadFile = this._uploadFile(param.getFiles(), "");             //读取excel             ExcelReadUtils readUtils = new ExcelReadUtils(uploadFile);             List<String> keyArr = Arrays.asList("10-19", "20-29", "30-39", "40-49", "50-59", "60-69");             List<Map<String, String>> data = readUtils.getAllDataMap(keyArr);             if( CollectionUtils.isNotEmpty(data) ){                 final int[] i = {1};                 data.forEach(item->{                     log.info("第"+ i[0] +"行:{}", JSONUtils.toJsonString(item));                     i[0]++;                 });             }             readUtils.close();             //写入excel             ExcelWriteUtils writeUtils = new ExcelWriteUtils("测试1");             if( CollectionUtils.isNotEmpty(data) ){                 final int[] rowIndex = {0};                 data.forEach(item->{                     List<String> valueArr = new ArrayList<>();                     keyArr.forEach(key->{                         valueArr.add( item.get(key) );                     });                     writeUtils.writeRow(rowIndex[0], valueArr);                     rowIndex[0]++;                 });             }             File targetFile = this._buildExcelFile(writeUtils.getWorkbook(), "");             return targetFile.getAbsolutePath();         } catch (Exception e) {             e.printStackTrace();             throw BaseException.logicException(e.getMessage());         } finally {             //删除上传的文件             if( uploadFile!=null && uploadFile.exists() ){ //                uploadFile.delete();             }         }     }     private File _uploadFile(MultipartFile srcFile, String dir) throws Exception{         // 根路径,在 resources/static/upload         String folderPath = ResourceUtils.getURL("classpath:").getPath() + "upload/" + (StringUtils.isNotBlank(dir) ? (dir + "/") : "");         File folder = new File(folderPath);         if( !folder.exists() ){             folder.mkdirs();         }         UUID uuid = UUID.randomUUID();         File targetFile = new File(folder.getAbsolutePath(), uuid+"_"+srcFile.getOriginalFilename());         srcFile.transferTo(targetFile);         return targetFile;     }      private File _buildExcelFile(XSSFWorkbook workbook, String dir) throws IOException {         // 根路径,在 resources/static/upload         String folderPath = ResourceUtils.getURL("classpath:").getPath() + "upload/" + (StringUtils.isNotBlank(dir) ? (dir + "/") : "");         File folder = new File(folderPath);         if( !folder.exists() ){             folder.mkdirs();         }         UUID uuid = UUID.randomUUID();         File targetFile = new File(folder.getAbsolutePath(), uuid+"_build_.xlsx");         OutputStream out = new FileOutputStream(targetFile);         workbook.write(out);         workbook.close();         out.close();         return targetFile;     } } 

4.3 页面

<!DOCTYPE html> <html> <head>     <meta charset="UTF-8" />     <title>excel测试</title>     <script src="./../scripts/jquery-3.3.1.min.js"></script>     <script src="./../scripts/jquery.form.js"></script> </head> <body> <form id="form" method="post" enctype="multipart/form-data">     <table>         <tr>             <td>文件</td>             <td>                 <input type="file" name="files"/>             </td>         </tr>     </table>     <input type="submit" value="上传" id="btnUpload"/> </form> <div id="result"></div> <script> $(function(){     var url = window.location.origin+"/szy-tools/excel/upload";     var download_url = window.location.origin+"/szy-tools/excel/download";     $("#form").ajaxForm({         url			: 	url,         type		: 	"POST",         dataType	: 	"json",         beforeSubmit: 	function(){             return true;         },         success: function(res){             if( res.state=="success" ){                 $("#result").text("成功:"+res.data);                 var t_url = download_url+"?filePath="+urlencode(res.data);                 window.open(t_url);             }else{                 $("#result").text("失败:"+res.message);             }         },         fail: function(res){             $("#result").text("失败:"+res);         }     }); }); function urlencode (str) {     str = (str + '').toString();      return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+'); } </script> </body> </html>

5.补充所有pom.xml

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 	<modelVersion>4.0.0</modelVersion> 	<parent> 		<groupId>org.springframework.boot</groupId> 		<artifactId>spring-boot-starter-parent</artifactId> 		<version>2.6.7</version> 		<relativePath/> <!-- lookup parent from repository --> 	</parent> 	<groupId>com.example</groupId> 	<artifactId>demo</artifactId> 	<version>0.0.1-SNAPSHOT</version> 	<name>szy-tools</name> 	<description>My tools project for Spring Boot</description> 	<!-- 打包配置 --> 	<packaging>jar</packaging>  	<properties> 		<java.version>1.8</java.version> 		<!-- 分布式RPC框架Motan--> 		<motan.version>1.1.6</motan.version> 		<org-apache-poi.version>3.17</org-apache-poi.version> 	</properties> 	<dependencies> 		<dependency> 			<groupId>org.springframework.boot</groupId> 			<artifactId>spring-boot-starter-web</artifactId> 		</dependency>  		<!-- 热部署 --> 		<dependency> 			<groupId>org.springframework.boot</groupId> 			<artifactId>spring-boot-devtools</artifactId> 			<optional>true</optional> 		</dependency>  		<dependency> 			<groupId>org.springframework.boot</groupId> 			<artifactId>spring-boot-starter-test</artifactId> 			<scope>test</scope> 		</dependency>  		<!-- thymeleaf,for html,jsp... --> 		<dependency> 			<groupId>org.springframework.boot</groupId> 			<artifactId>spring-boot-starter-thymeleaf</artifactId> 		</dependency>  		<!-- json.start --> 		<dependency> 			<groupId>org.codehaus.jackson</groupId> 			<artifactId>jackson-mapper-asl</artifactId> 			<version>1.9.13</version> 		</dependency> 		<!-- jackson默认不支持java8的时间类型,需要添加一个时间模块 --> 		<dependency> 			<groupId>com.fasterxml.jackson.datatype</groupId> 			<artifactId>jackson-datatype-jsr310</artifactId> 		</dependency> 		<!-- json.end -->  		<!--lombok用来简化实体类--> 		<dependency> 			<groupId>org.projectlombok</groupId> 			<artifactId>lombok</artifactId> 			<optional>true</optional> 		</dependency>  		<dependency> 			<groupId>org.apache.commons</groupId> 			<artifactId>commons-lang3</artifactId> 			<version>3.8.1</version> 		</dependency>  		<!-- Knife4j在线API文档的依赖 --> 		<dependency> 			<groupId>com.github.xiaoymin</groupId> 			<artifactId>knife4j-spring-boot-starter</artifactId> 			<version>3.0.3</version> 		</dependency>  	<!-- httpclient.start --> 		<dependency> 			<groupId>org.apache.httpcomponents</groupId> 			<artifactId>httpclient</artifactId> 		</dependency> 	<!-- httpclient.end -->  	<!-- smb.start --> 		<!--支持文件共享SMB1协议--> 		<dependency> 			<groupId>org.samba.jcifs</groupId> 			<artifactId>jcifs</artifactId> 			<version>1.3.3</version> 		</dependency> 		<!--支持文件共享SMB2/3协议--> 		<dependency> 			<groupId>com.hierynomus</groupId> 			<artifactId>smbj</artifactId> 			<version>0.10.0</version> 		</dependency> 	<!-- smb.end -->  	<!-- user-agent工具类.start --> 		<dependency> 			<groupId>eu.bitwalker</groupId> 			<artifactId>UserAgentUtils</artifactId> 			<version>1.21</version> 		</dependency> 	<!-- user-agent工具类.end -->  	<!--poi.start --> 		<dependency> 			<groupId>org.apache.poi</groupId> 			<artifactId>poi</artifactId> 			<version>${org-apache-poi.version}</version> 		</dependency> 		<dependency> 			<groupId>org.apache.poi</groupId> 			<artifactId>poi-excelant</artifactId> 			<version>${org-apache-poi.version}</version> 		</dependency> 		<dependency> 			<groupId>org.apache.poi</groupId> 			<artifactId>poi-ooxml</artifactId> 			<version>3.15</version> 		</dependency> 	<!--poi.end -->  	</dependencies>  	<build> 		<!-- 指定生成的jar包名称 --> 		<finalName>szy-tools</finalName> 		<plugins> 			<plugin> 				<groupId>org.springframework.boot</groupId> 				<artifactId>spring-boot-maven-plugin</artifactId> 			</plugin> 		</plugins> 	</build>  </project>