当前位置:   article > 正文

java导出excel 【POI 3.17】POI 版本不匹配解决方法_cannot resolve org.apache.poi:poi-ooxml:3.17

cannot resolve org.apache.poi:poi-ooxml:3.17

目录 

1.Maven依赖

2.ExcelUtil工具类代码

3.Test测试

4.遇到的问题


公司要写导出Excel的功能,就写了一下,顺便记录记录,代码从这里copy来的,自己改了一下。源码应该是3.9的poi版本,里面挺多类已经不推荐使用了,我用的poi是3.17。

1.Maven依赖

  1. <!-- 数据导出到xlsx -->
  2. <dependency>
  3. <groupId>org.apache.xmlbeans</groupId>
  4. <artifactId>xmlbeans</artifactId>
  5. <version>2.6.0</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.apache.poi</groupId>
  9. <artifactId>poi</artifactId>
  10. <version>3.17</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.apache.poi</groupId>
  14. <artifactId>poi-ooxml</artifactId>
  15. <version>3.17</version>
  16. </dependency>

 2.ExcelUtil工具类代码

  1. import org.apache.poi.ss.usermodel.BorderStyle;
  2. import org.apache.poi.ss.usermodel.CellType;
  3. import org.apache.poi.ss.usermodel.HorizontalAlignment;
  4. import org.apache.poi.ss.usermodel.VerticalAlignment;
  5. import org.apache.poi.ss.util.CellRangeAddress;
  6. import org.apache.poi.xssf.usermodel.*;
  7. import javax.servlet.http.HttpServletResponse;
  8. import java.awt.*;
  9. import java.io.IOException;
  10. import java.io.OutputStream;
  11. import java.util.List;
  12. import static org.apache.poi.ss.usermodel.CellType.NUMERIC;
  13. public class ExcelUtil {
  14. /**
  15. * 导出excel
  16. *
  17. * @param title 导出表的标题
  18. * @param rowsName 导出表的列名
  19. * @param dataList 需要导出的数据
  20. * @param fileName 生成excel文件的文件名
  21. * @param response
  22. */
  23. public void exportExcel(String title, String[] rowsName, List<String[]> dataList, String fileName, HttpServletResponse response) throws Exception {
  24. OutputStream output = response.getOutputStream();
  25. response.reset();
  26. response.setHeader("Content-disposition",
  27. "attachment; filename=" + fileName);
  28. response.setContentType("application/msexcel");
  29. this.export(title, rowsName, dataList, fileName, output);
  30. this.close(output);
  31. }
  32. /**
  33. * 数据导出
  34. * @param title
  35. * @param rowName
  36. * @param dataList
  37. * @param fileName
  38. * @param out
  39. * @throws Exception
  40. */
  41. private void export(String title, String[] rowName, List<String[]> dataList, String fileName, OutputStream out) throws Exception {
  42. //查看poi使用的是什么版本的jar包
  43. //System.out.println("!!!!!!!!!"+ XSSFCellStyle.class.getProtectionDomain().getCodeSource().getLocation());
  44. try {
  45. // 创建工作簿对象
  46. XSSFWorkbook workbook = new XSSFWorkbook();
  47. // 创建工作表
  48. XSSFSheet sheet = workbook.createSheet(title);
  49. // 产生表格标题行
  50. XSSFRow rowm = sheet.createRow(0);
  51. //创建表格标题列
  52. XSSFCell cellTiltle = rowm.createCell(0);
  53. // sheet样式定义; getColumnTopStyle(); getStyle()均为自定义方法 --在下面,可扩展
  54. // 获取列头样式对象
  55. XSSFCellStyle columnTopStyle = this.getColumnTopStyle(workbook);
  56. // 获取单元格样式对象
  57. XSSFCellStyle style = this.getStyle(workbook);
  58. //合并表格标题行,合并列数为列名的长度,第一个0为起始行号,第二个1为终止行号,第三个0为起始列好,第四个参数为终止列号
  59. sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, (rowName.length - 1)));
  60. //设置标题行样式
  61. cellTiltle.setCellStyle(columnTopStyle);
  62. //设置标题行值
  63. cellTiltle.setCellValue(title);
  64. // 定义所需列数
  65. int columnNum = rowName.length;
  66. // 在索引2的位置创建行(最顶端的行开始的第二行)
  67. XSSFRow rowRowName = sheet.createRow(2);
  68. // 将列头设置到sheet的单元格中
  69. for (int n = 0; n < columnNum; n++) {
  70. // 创建列头对应个数的单元格
  71. XSSFCell cellRowName = rowRowName.createCell(n);
  72. // 设置列头单元格的数据类型
  73. cellRowName.setCellType(CellType.STRING);
  74. XSSFRichTextString text = new XSSFRichTextString(rowName[n]);
  75. // 设置列头单元格的值
  76. cellRowName.setCellValue(text);
  77. // 设置列头单元格样式
  78. cellRowName.setCellStyle(columnTopStyle);
  79. }
  80. // 将查询出的数据设置到sheet对应的单元格中
  81. for (int i = 0; i < dataList.size(); i++) {
  82. // 遍历每个对象
  83. Object[] obj = dataList.get(i);
  84. // 创建所需的行数
  85. XSSFRow row = sheet.createRow(i + 3);
  86. for (int j = 0; j < obj.length; j++) {
  87. // 设置单元格的数据类型
  88. XSSFCell cell = null;
  89. if (j == 0) {
  90. cell = row.createCell(j, NUMERIC);
  91. cell.setCellValue(i + 1);
  92. } else {
  93. cell = row.createCell(j, CellType.STRING);
  94. if (!"".equals(obj[j]) && obj[j] != null) {
  95. // 设置单元格的值
  96. cell.setCellValue(obj[j].toString());
  97. }
  98. }
  99. cell.setCellStyle(style); // 设置单元格样式
  100. }
  101. }
  102. // 让列宽随着导出的列长自动适应
  103. for (int colNum = 0; colNum < columnNum; colNum++) {
  104. int columnWidth = sheet.getColumnWidth(colNum) / 256;
  105. for (int rowNum = 0; rowNum < sheet.getLastRowNum(); rowNum++) {
  106. XSSFRow currentRow;
  107. // 当前行未被使用过
  108. if (sheet.getRow(rowNum) == null) {
  109. currentRow = sheet.createRow(rowNum);
  110. } else {
  111. currentRow = sheet.getRow(rowNum);
  112. }
  113. if (currentRow.getCell(colNum) != null) {
  114. XSSFCell currentCell = currentRow.getCell(colNum);
  115. if (currentCell.getCellType() == 1) {
  116. int length = currentCell.getStringCellValue()
  117. .getBytes().length;
  118. if (columnWidth < length) {
  119. columnWidth = length;
  120. }
  121. }
  122. }
  123. }
  124. if (colNum == 0) {
  125. sheet.setColumnWidth(colNum, (columnWidth - 2) * 256);
  126. } else {
  127. sheet.setColumnWidth(colNum, (columnWidth + 8) * 256);
  128. }
  129. }
  130. workbook.write(out);
  131. } catch (Exception e) {
  132. e.printStackTrace();
  133. }
  134. }
  135. /*
  136. * 列头单元格样式
  137. */
  138. private XSSFCellStyle getColumnTopStyle(XSSFWorkbook workbook) {
  139. // 设置字体
  140. XSSFFont font = workbook.createFont();
  141. // 设置字体大小
  142. font.setFontHeightInPoints((short) 16);
  143. // 字体加粗
  144. font.setBold(true);
  145. // 设置字体名字
  146. font.setFontName("Courier New");
  147. // 设置样式;
  148. XSSFCellStyle style = workbook.createCellStyle();
  149. // 设置底边框;
  150. style.setBorderBottom(BorderStyle.THIN);
  151. // 设置底边框颜色;
  152. style.setBottomBorderColor(new XSSFColor(Color.BLACK));
  153. // 设置左边框;
  154. style.setBorderLeft(BorderStyle.THIN);
  155. // 设置左边框颜色;
  156. style.setLeftBorderColor(new XSSFColor(Color.BLACK));
  157. // 设置右边框;
  158. style.setBorderRight(BorderStyle.THIN);
  159. // 设置右边框颜色;
  160. style.setRightBorderColor(new XSSFColor(Color.BLACK));
  161. // 设置顶边框;
  162. style.setBorderTop(BorderStyle.THIN);
  163. // 设置顶边框颜色;
  164. style.setTopBorderColor(new XSSFColor(Color.BLACK));
  165. // 在样式用应用设置的字体;
  166. style.setFont(font);
  167. // 设置自动换行;
  168. style.setWrapText(false);
  169. // 设置水平对齐的样式为居中对齐;
  170. style.setAlignment(HorizontalAlignment.CENTER);
  171. // 设置垂直对齐的样式为居中对齐;
  172. style.setVerticalAlignment(VerticalAlignment.CENTER);
  173. return style;
  174. }
  175. /*
  176. * 列数据信息单元格样式
  177. */
  178. private XSSFCellStyle getStyle(XSSFWorkbook workbook) {
  179. // 设置字体
  180. XSSFFont font = workbook.createFont();
  181. // 设置字体大小
  182. // font.setFontHeightInPoints((short)10);
  183. // 字体加粗
  184. // font.setBold(true);
  185. // 设置字体名字
  186. font.setFontName("Courier New");
  187. // 设置样式;
  188. XSSFCellStyle style = workbook.createCellStyle();
  189. // 设置底边框;
  190. style.setBorderBottom(BorderStyle.THIN);
  191. // 设置底边框颜色;
  192. //style.setBottomBorderColor(new XSSFColor(Color.RED));
  193. // 设置左边框;
  194. style.setBorderLeft(BorderStyle.THIN);
  195. // 设置左边框颜色;
  196. style.setLeftBorderColor(new XSSFColor(Color.BLACK));
  197. // 设置右边框;
  198. style.setBorderRight(BorderStyle.THIN);
  199. // 设置右边框颜色;
  200. style.setRightBorderColor(new XSSFColor(Color.BLACK));
  201. // 设置顶边框;
  202. style.setBorderTop(BorderStyle.THIN);
  203. // 设置顶边框颜色;
  204. style.setTopBorderColor(new XSSFColor(Color.BLACK));
  205. // 在样式用应用设置的字体;
  206. style.setFont(font);
  207. // 设置自动换行;
  208. style.setWrapText(false);
  209. // 设置水平对齐的样式为居中对齐;
  210. style.setAlignment(HorizontalAlignment.CENTER);
  211. // 设置垂直对齐的样式为居中对齐;
  212. style.setVerticalAlignment(VerticalAlignment.CENTER);
  213. return style;
  214. }
  215. /**
  216. * 关闭输出流
  217. *
  218. * @param os
  219. */
  220. private void close(OutputStream os) {
  221. if (os != null) {
  222. try {
  223. os.close();
  224. } catch (IOException e) {
  225. e.printStackTrace();
  226. }
  227. }
  228. }
  229. }

 3.Test测试

  1. @GetMapping("/test")
  2. public R test(HttpServletResponse response) {
  3. ExcelUtil excelUtil = new ExcelUtil();
  4. List<String[]> el = new ArrayList<>();
  5. //需要导出的数据
  6. List<ReportLogDataDto> reportList = reportService.getReportList();
  7. if (reportList.isEmpty()) {
  8. return R.failed("查询到的报表条数为0");
  9. }
  10. //遍历取出数据,封装成List<String[]>的形式
  11. reportList.forEach(item -> {
  12. int count = 0;
  13. String[] col = new String[8];
  14. //这行是给编号留出一个空位
  15. col[count++] = "";
  16. col[count++] = item.getCode();
  17. col[count++] = item.getRoomName();
  18. col[count++] = item.getStartTime();
  19. col[count++] = item.getEndTime();
  20. col[count++] = item.getIsFinished();
  21. col[count++] = item.getFailureReason();
  22. col[count++] = item.getTime();
  23. el.add(col);
  24. });
  25. //这里是列名
  26. String[] name = {"编号", "设备编号", "房间名", "开始时间", "结束时间", "是否完成消毒", "失败原因", "时间段"};
  27. try {
  28. excelUtil.exportExcel("消毒报表", name, el, "DisinfectionReport.xlsx", response);
  29. System.out.println("excel finished");
  30. } catch (Exception e) {
  31. e.printStackTrace();
  32. }
  33. return R.ok();
  34. }

我是用SwaggerUI看的,结果如下: 

 4.遇到的问题

1)jar包的升级导致CELL_TYPE_STRING、XSSFCell.CELL_TYPE_NUMERIC等无法使用

    可以使用CellType.STRING、CellType.NUMERIC等等代替。图片是CellType中的内容,可以看出,从3.15就可以使用新的参数了。新的版本都会有旧版本的替代方法,改改就好了。

 

    同时,以下也可以进行替换

POI旧版本POI新版本
HSSFCellStyle.BORDER_THINBorderStyle.THIN
HSSFColor.BLACK.indexnew XSSFColor(Color.BLACK)
HSSFCellStyle.ALIGN_CENTERHorizontalAlignment.CENTER
HSSFCellStyle.VERTICAL_CENTERVerticalAlignment.CENTER

2)Caused by: java.lang.NoSuchMethodError: org.apache.poi.hssf.usermodel.XSSFCell.setEncoding(S)V 

    这可能是由于poi版本覆盖,或者没有正确的引用poi的jar包导致的,我最开始用的jar包,应该是poi3.9,但是下载依赖的时候,会自动把3.17的版本也下载下来,自动覆盖了3.9的版本,导致虽然没有报错,但是 HSSFCellStyle 和部分class一直提示NoSuchMethodError。

    ExcelUtil代码中有一行sysout语句如下,这行会把使用的class所在的路径打印出来,通过打印出的信息,可以看看自己用的jar包到底是哪里的,版本号是多少,这个其实也算是版本升级导致的问题了。建议使用新版本的poi,别用老的了。

 

System.out.println("!!!!!!!!!"+ XSSFCellStyle.class.getProtectionDomain().getCodeSource().getLocation());

 

引用:

https://www.cnblogs.com/duanrantao/p/8683022.html

https://www.cnblogs.com/qxqbk/p/7655307.html

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号