精华内容
下载资源
问答
  • 解决easyExcel和poi版本冲突问题

    千次阅读 2021-03-12 06:47:32
    由于easyExcel自带依赖于3.17的poi,所以如果项目其它地方映入了其它版本的poi,就会导致easyExcel导出失败等一系列问题,主要原因是因为poi版本冲突导致的,这里我提供的解决办法是,引入easyExcel的时候,排出...

    由于easyExcel自带依赖于3.17的poi,所以如果项目其它地方映入了其它版本的poi,就会导致easyExcel导出失败等一系列问题,主要原因是因为poi版本冲突导致的,这里我提供的解决办法是,引入easyExcel的时候,排出easyExcel中自带的poi依赖。

    本方法已通过博主的亲自实践,方法有效解决版本冲突导致的一系列的问题。在网上查询相关资料的时候,发现解决方法有很多,这个解决方法并不是唯一的解决办法,由于时间精力有限,其它的方法就没有去进行实践验证了,有兴趣的可以查找相关资料实践。

       <!--集成EasyExcel -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>easyexcel</artifactId>
                <version>2.2.6</version>
                <exclusions>
                    <exclusion>
                        <groupId>javax.servlet</groupId>
                        <artifactId>servlet-api</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.poi</groupId>
                        <artifactId>poi</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.poi</groupId>
                        <artifactId>poi-ooxml</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.poi</groupId>
                        <artifactId>poi-ooxml-schemas</artifactId>
                    </exclusion>
                </exclusions>
             </dependency>

     

    展开全文
  • 目录 1.Maven依赖 2.ExcelUtil工具类代码 ...源码应该是3.9的poi版本,里面挺多类已经不推荐使用了,我用的poi是3.17。 1.Maven依赖 <!-- 数据导出到xlsx --> <dependency&g...

    目录 

    1.Maven依赖

    2.ExcelUtil工具类代码

    3.Test测试

    4.遇到的问题


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

    1.Maven依赖

    		<!-- 数据导出到xlsx -->
    		<dependency>
    			<groupId>org.apache.xmlbeans</groupId>
    			<artifactId>xmlbeans</artifactId>
    			<version>2.6.0</version>
    		</dependency>
    		<dependency>
    			<groupId>org.apache.poi</groupId>
    			<artifactId>poi</artifactId>
    			<version>3.17</version>
    		</dependency>
    		<dependency>
    			<groupId>org.apache.poi</groupId>
    			<artifactId>poi-ooxml</artifactId>
    			<version>3.17</version>
    		</dependency>

     2.ExcelUtil工具类代码

    import org.apache.poi.ss.usermodel.BorderStyle;
    import org.apache.poi.ss.usermodel.CellType;
    import org.apache.poi.ss.usermodel.HorizontalAlignment;
    import org.apache.poi.ss.usermodel.VerticalAlignment;
    import org.apache.poi.ss.util.CellRangeAddress;
    import org.apache.poi.xssf.usermodel.*;
    
    import javax.servlet.http.HttpServletResponse;
    import java.awt.*;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.List;
    
    import static org.apache.poi.ss.usermodel.CellType.NUMERIC;
    
    public class ExcelUtil {
    
    	/**
    	 * 导出excel
    	 *
    	 * @param title    导出表的标题
    	 * @param rowsName 导出表的列名
    	 * @param dataList 需要导出的数据
    	 * @param fileName 生成excel文件的文件名
    	 * @param response
    	 */
    	public void exportExcel(String title, String[] rowsName, List<String[]> dataList, String fileName, HttpServletResponse response) throws Exception {
    		OutputStream output = response.getOutputStream();
    		response.reset();
    		response.setHeader("Content-disposition",
    				"attachment; filename=" + fileName);
    		response.setContentType("application/msexcel");
    		this.export(title, rowsName, dataList, fileName, output);
    		this.close(output);
    	}
    
    	/**
    	 * 数据导出
    	 * @param title
    	 * @param rowName
    	 * @param dataList
    	 * @param fileName
    	 * @param out
    	 * @throws Exception
    	 */
    	private void export(String title, String[] rowName, List<String[]> dataList, String fileName, OutputStream out) throws Exception {
    		//查看poi使用的是什么版本的jar包
    		//System.out.println("!!!!!!!!!"+ XSSFCellStyle.class.getProtectionDomain().getCodeSource().getLocation());
    		try {
    			// 创建工作簿对象
    			XSSFWorkbook workbook = new XSSFWorkbook();
    			// 创建工作表
    			XSSFSheet sheet = workbook.createSheet(title);
    			// 产生表格标题行
    			XSSFRow rowm = sheet.createRow(0);
    			//创建表格标题列
    			XSSFCell cellTiltle = rowm.createCell(0);
    			// sheet样式定义;    getColumnTopStyle();    getStyle()均为自定义方法 --在下面,可扩展
    			// 获取列头样式对象
    			XSSFCellStyle columnTopStyle = this.getColumnTopStyle(workbook);
    			// 获取单元格样式对象
    			XSSFCellStyle style = this.getStyle(workbook);
    			//合并表格标题行,合并列数为列名的长度,第一个0为起始行号,第二个1为终止行号,第三个0为起始列好,第四个参数为终止列号
    			sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, (rowName.length - 1)));
    			//设置标题行样式
    			cellTiltle.setCellStyle(columnTopStyle);
    			//设置标题行值
    			cellTiltle.setCellValue(title);
    			// 定义所需列数
    			int columnNum = rowName.length;
    			// 在索引2的位置创建行(最顶端的行开始的第二行)
    			XSSFRow rowRowName = sheet.createRow(2);
    			// 将列头设置到sheet的单元格中
    			for (int n = 0; n < columnNum; n++) {
    				// 创建列头对应个数的单元格
    				XSSFCell cellRowName = rowRowName.createCell(n);
    				// 设置列头单元格的数据类型
    				cellRowName.setCellType(CellType.STRING);
    				XSSFRichTextString text = new XSSFRichTextString(rowName[n]);
    				// 设置列头单元格的值
    				cellRowName.setCellValue(text);
    				// 设置列头单元格样式
    				cellRowName.setCellStyle(columnTopStyle);
    			}
    
    			// 将查询出的数据设置到sheet对应的单元格中
    			for (int i = 0; i < dataList.size(); i++) {
    				// 遍历每个对象
    				Object[] obj = dataList.get(i);
    				// 创建所需的行数
    				XSSFRow row = sheet.createRow(i + 3);
    				for (int j = 0; j < obj.length; j++) {
    					// 设置单元格的数据类型
    					XSSFCell cell = null;
    					if (j == 0) {
    						cell = row.createCell(j, NUMERIC);
    						cell.setCellValue(i + 1);
    					} else {
    						cell = row.createCell(j, CellType.STRING);
    						if (!"".equals(obj[j]) && obj[j] != null) {
    							// 设置单元格的值
    							cell.setCellValue(obj[j].toString());
    						}
    					}
    					cell.setCellStyle(style); // 设置单元格样式
    				}
    			}
    
    			// 让列宽随着导出的列长自动适应
    			for (int colNum = 0; colNum < columnNum; colNum++) {
    				int columnWidth = sheet.getColumnWidth(colNum) / 256;
    				for (int rowNum = 0; rowNum < sheet.getLastRowNum(); rowNum++) {
    					XSSFRow currentRow;
    					// 当前行未被使用过
    					if (sheet.getRow(rowNum) == null) {
    						currentRow = sheet.createRow(rowNum);
    					} else {
    						currentRow = sheet.getRow(rowNum);
    					}
    					if (currentRow.getCell(colNum) != null) {
    						XSSFCell currentCell = currentRow.getCell(colNum);
    						if (currentCell.getCellType() == 1) {
    							int length = currentCell.getStringCellValue()
    									.getBytes().length;
    							if (columnWidth < length) {
    								columnWidth = length;
    							}
    						}
    					}
    				}
    				if (colNum == 0) {
    					sheet.setColumnWidth(colNum, (columnWidth - 2) * 256);
    				} else {
    					sheet.setColumnWidth(colNum, (columnWidth + 8) * 256);
    				}
    			}
    			workbook.write(out);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    
    	/*
    	 * 列头单元格样式
    	 */
    	private XSSFCellStyle getColumnTopStyle(XSSFWorkbook workbook) {
    
    		// 设置字体
    		XSSFFont font = workbook.createFont();
    		// 设置字体大小
    		font.setFontHeightInPoints((short) 16);
    		// 字体加粗
    		font.setBold(true);
    		// 设置字体名字
    		font.setFontName("Courier New");
    		// 设置样式;
    		XSSFCellStyle style = workbook.createCellStyle();
    		// 设置底边框;
    		style.setBorderBottom(BorderStyle.THIN);
    		// 设置底边框颜色;
    		style.setBottomBorderColor(new XSSFColor(Color.BLACK));
    		// 设置左边框;
    		style.setBorderLeft(BorderStyle.THIN);
    		// 设置左边框颜色;
    		style.setLeftBorderColor(new XSSFColor(Color.BLACK));
    		// 设置右边框;
    		style.setBorderRight(BorderStyle.THIN);
    		// 设置右边框颜色;
    		style.setRightBorderColor(new XSSFColor(Color.BLACK));
    		// 设置顶边框;
    		style.setBorderTop(BorderStyle.THIN);
    		// 设置顶边框颜色;
    		style.setTopBorderColor(new XSSFColor(Color.BLACK));
    		// 在样式用应用设置的字体;
    		style.setFont(font);
    		// 设置自动换行;
    		style.setWrapText(false);
    		// 设置水平对齐的样式为居中对齐;
    		style.setAlignment(HorizontalAlignment.CENTER);
    		// 设置垂直对齐的样式为居中对齐;
    		style.setVerticalAlignment(VerticalAlignment.CENTER);
    
    		return style;
    
    	}
    
    	/*
    	 * 列数据信息单元格样式
    	 */
    	private XSSFCellStyle getStyle(XSSFWorkbook workbook) {
    		// 设置字体
    		XSSFFont font = workbook.createFont();
    		// 设置字体大小
    		// font.setFontHeightInPoints((short)10);
    		// 字体加粗
    		// font.setBold(true);
    		// 设置字体名字
    		font.setFontName("Courier New");
    		// 设置样式;
    		XSSFCellStyle style = workbook.createCellStyle();
    		// 设置底边框;
    		style.setBorderBottom(BorderStyle.THIN);
    		// 设置底边框颜色;
    		//style.setBottomBorderColor(new XSSFColor(Color.RED));
    		// 设置左边框;
    		style.setBorderLeft(BorderStyle.THIN);
    		// 设置左边框颜色;
    		style.setLeftBorderColor(new XSSFColor(Color.BLACK));
    		// 设置右边框;
    		style.setBorderRight(BorderStyle.THIN);
    		// 设置右边框颜色;
    		style.setRightBorderColor(new XSSFColor(Color.BLACK));
    		// 设置顶边框;
    		style.setBorderTop(BorderStyle.THIN);
    		// 设置顶边框颜色;
    		style.setTopBorderColor(new XSSFColor(Color.BLACK));
    		// 在样式用应用设置的字体;
    		style.setFont(font);
    		// 设置自动换行;
    		style.setWrapText(false);
    		// 设置水平对齐的样式为居中对齐;
    		style.setAlignment(HorizontalAlignment.CENTER);
    		// 设置垂直对齐的样式为居中对齐;
    		style.setVerticalAlignment(VerticalAlignment.CENTER);
    		return style;
    	}
    
    	/**
    	 * 关闭输出流
    	 *
    	 * @param os
    	 */
    	private void close(OutputStream os) {
    		if (os != null) {
    			try {
    				os.close();
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    
    }
    
    

     3.Test测试

    @GetMapping("/test")
    public R test(HttpServletResponse response) {
    	ExcelUtil excelUtil = new ExcelUtil();
    	List<String[]> el = new ArrayList<>();
    
    	//需要导出的数据
    	List<ReportLogDataDto> reportList = reportService.getReportList();
    
    	if (reportList.isEmpty()) {
    		return R.failed("查询到的报表条数为0");
    	}
    
    	//遍历取出数据,封装成List<String[]>的形式
    	reportList.forEach(item -> {
    		int count = 0;
    		String[] col = new String[8];
                    //这行是给编号留出一个空位
    		col[count++] = "";
    		col[count++] = item.getCode();
    		col[count++] = item.getRoomName();
    		col[count++] = item.getStartTime();
    		col[count++] = item.getEndTime();
    		col[count++] = item.getIsFinished();
    		col[count++] = item.getFailureReason();
    		col[count++] = item.getTime();
    		el.add(col);
    	});
    
    	//这里是列名
    	String[] name = {"编号", "设备编号", "房间名", "开始时间", "结束时间", "是否完成消毒", "失败原因", "时间段"};
    	try {
    		excelUtil.exportExcel("消毒报表", name, el, "DisinfectionReport.xlsx", response);
    		System.out.println("excel finished");
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    	return R.ok();
    }

    我是用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

    展开全文
  • Poi版本升级优化

    2021-09-20 10:06:05
    Poi-3.17前后版本api使用差异 1. 升级缘由 最近公司prod环境出现因为Excel文件下载数据量过大导致应用out of memory, 然后就需要找到内存溢出的原因及优化方案. 经分析, 得出以下结论: 1.1 事故原因 (1) 应用场景...

    Poi-3.17前后版本api使用差异

    1. 升级缘由

    最近公司prod环境出现因为Excel文件下载数据量过大导致应用out of memory, 然后就需要找到内存溢出的原因及优化方案. 经分析, 得出以下结论:

    1.1 事故原因

    (1) 应用场景发生在页面列表查询功能, 可以批量勾选列表项选择下载, 后台又需要根据勾选的列表项字段关联查询出N+条大量明细数据, 系统程序又没有对大数据量做评估校验, 一路绿灯,最终形成社会性死亡现场 . 导致宕机的主要原因倒不是因为单个请求线程的数据量过大导致, 当前请求最多不过是下载失败, 真正导致应用宕机是因为前端界面一直展示下载加载效果, 用户一直重复点击, 多个请求线程访问应用, 熟悉POI的老铁们应该都知道, POI生成DOM节点需要消耗大量的内存, 结果就是开头的out of memory了.

    (2) 系统监控平台发现大量接口请求超时, 为了不影响后续其他业务的正常作业, 立即展开抢救, 过程就是根据导致宕机的请求数据找到操作用户(因为是内网用户, 可以查到用户联系方式), 然后打电话给那位用户说明情况并让其不要再重复点击, 最后就是重启Server了, 很多问题都是重启可以搞定的哈, 当然我们是主从2台机器, 所以停机重启不会大面积影响业务, 请求会经F5负载均衡转发到另外一台正常运行的机器上去 .

    (3) 经过在测试环境复现事故场景, 发现超过65536条(含标题行)记录就会报错, 相信用过Poi的老铁们都知道了, 我们程序使用的是POIHSSF创建的Workbook工作簿, 也就是创建的2003版Excel文件(xls), 最多仅支持65536行记录写入(0-65535), 超过这个量的数据下载肯定会报错了. 下面是我自己测试复现的报错截图:

    image-20210919110849540

    1.2 优化方案

    分析出上面的问题原因后, 我也查阅了操作Excel相关的技术, 尝试了下面几种解决方案.

    1.2.1 改用XSSF生成

    针对上面HSSF只能写入65536行记录的局限, POI也是给出了解决方案的, XSSF创建的Workbook工作簿, 生成的是2007版Excel(xlsx), 支持上限1048576行记录的写入 , 基本满足我们日常的应用场景了. 另外在XSSF基础上, POI-3.8版本开始提供的支持低内存占用的操作方式SXSSFWorkbook, 支持2007以上版本的Excel操作.

    关键代码体现 :

    /**
     * 根据要生成的文件类型创建HSSF或者XSSF工作簿
     * @param fileType .xls .xlsx
     * @return
     */
    public static Workbook getWorkbook(String fileType) {
        Workbook wb = null;
        switch (fileType) {
            case CSISCONSTANT.EXCEL03_EXTENSION:
                wb = new HSSFWorkbook(); // 创建工作簿 2003版excel
                break;
            case CSISCONSTANT.EXCEL07_EXTENSION:
            default:
                wb = new XSSFWorkbook(); // 创建工作簿 2007版excel
                break;
        }
        return wb;
    }
    

    具体实现代码请移步博客Poi实现Excel导出

    1.2.2 数据拆分文件压缩

    XSSF方案只是解决了大数据量写入的问题, 从系统安全性和性能方面考虑, 还有更多的优化空间. 程序现状没有对数据做分流处理, 依然是全部数据一次性生成并写入Excel文件, 对内存的消耗仍旧很糟糕. 其实可以对查询出来的大量数据根据自己设置的阈值做分流处理, 阈值设置在1万-2万之间, 因为打开一个Excel文件当前Sheet页方便快速翻阅查看最好了, 数据写入太多翻页查看数据会很卡, 用户体验不好. 根据阈值分流后的数据在性能允许范围内, 循环调用提前封装好的生成Excel文件的方法, 每次循环生成后Excel文件后, 会释放掉POI消耗的内存, 相比较一次性生成并写入Excel文件内存的占用时间和消耗小很多. 待所有Excel文件生成完成, 最后将这些文件打包压缩成zip文件流返回给界面.

    另外, SpringMVC中的Web端文件下载是在当前请求线程内完成的, 在生成并写入数据文件的过程中, 界面只能等着后端系统的响应, 且当前请求的线程会一直被占用着, 数据量不大还好, 如果数据量很大会影响用户体验. 我工作中用到的是前后端分离的项目, 文件下载是异步请求实现的, 设计思想就是界面发起文件下载的异步请求, 后台程序将生成的数据文件存放到服务器临时下载目录中 , 将临时下载目录的数据文件路径以流的形式返回给前端界面, 前端使用封装好的api直接去服务器临时下载目录中下载文件即可, 而不需要将整个数据文件以流的形式返回给前端界面. 文件上传也可以采用这种思想, 前端将文件直接上传到服务器临时上传目录中, 将文件路径提交到后台系统, 后台程序直接去服务器临时上传目录中读取解析.

    数据分流生成Excel的实现代码请移步博客 数据分流写入Excel

    文件压缩的实现代码请移步博客 Poi实现Excel导出

    1.2.3 使用开源技术EasyExcel

    EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百MB的Excel文件. 阿里的大牛们对POI进行了各种封装和优化, 不管是性能还是内存消耗方面都是质的飞跃, 在api使用方面也极具人性化, 简单易用.

    说明: EasyExcel底层是依赖POI的, 最低版本的EasyExcel要求POI-3.17版本, 如果我用这个方案, 必然面临POI版本升级问题, 因为POI-3.17版本相比POI3.17以下的版本, 在样式设置和单元格数据类型设置等方面改动比较大, 很多API进行了抽取. 项目组的系统有很多文件下载功能, 不能因为这个场景的问题全面改造, 没有测试人力的全面支持, 无法形成有效的升级. 后面我采用了数据分流写入并压缩的方案, 避免了POI版本升级的麻烦. 但是作为一名技术宅男, 肯定是不会放过这个优化方案的, 自己业余时间搭建了demo进行了冲突aip的升级改造, 具体冲突api的使用请见 Poi升级 .

    EasyExcel请移步博客 EasyExcel学习笔记

    1.2.4 其他

    除了原生POI, EasyExcel外, 还有其他相关技术可以实现Excel的操作, 比如EasyPoi, Hutool-poi, jxl等.

    EasyPoi请移步博客 EasyPoi学习笔记

    Hutool-poi请参考Hutool官方文档中的office文档操作部分.

    2. Poi升级

    POI3.17与POI旧版本对比, 有很多API的使用改变了, 下面将依次列出它们的不同及新API的使用.

    2.1 颜色定义

    旧版本

    HSSFColor.GREEN.index
    HSSFColor.BLACK.index   
    

    新版本

    IndexedColors.GREEN.getIndex()
    IndexedColors.GREEN.index
    IndexedColors.BLACK.getIndex()
    IndexedColors.BLACK.index
    

    2.2 获取单元格格式

    旧版本

    // 获取单元格格式
    int cellType = cell.getCellType(); 
    // 与之对应的单元格格式int值 
    HSSFCell.CELL_TYPE_BLANK  // 空
    HSSFCell.CELL_TYPE_STRING // 字符串
    HSSFCell.CELL_TYPE_NUMERIC // 数字类型   
    HSSFCell.CELL_TYPE_BOOLEAN // 布尔
    HSSFCell.CELL_TYPE_FORMULA // 公式   
    HSSFCell.CELL_TYPE_ERROR // 错误   
    

    新版本

    CellType cellTypeEnum = cell.getCellTypeEnum(); // 获取单元格格式
    // 与之对应的单元格格式枚举值 
    CellType.BLANK // 空
    CellType.STRING // 字符串   
    CellType.NUMERIC // 数字类型   
    CellType.BOOLEAN // 布尔   
    CellType.FORMULA // 公式
    CellType.ERROR // 错误   
    

    2.3 设置单元格数据类型

    旧版本

    Cell cell = row.getCell(0); // 获取单元格对象
    cell.setCellType(Cell.CELL_TYPE_STRING); // 设置单元格为字符串类型
    

    新版本

    Cell cell = row.getCell(0); // 获取单元格对象
    cell.setCellType(CellType.STRING); // 设置单元格为字符串类型
    

    2.4 设置单元格样式

    单元格样式包含垂直居中样式, 边框样式, 背景填充颜色, 边框线条等…

    旧版本

    HSSFCellStyle cellStyle = wb.createCellStyle();
    // XSSFCellStyle cellStyle = wb.createCellStyle();
    cellStyle.setFillForegroundColor(HSSFColor.LIME.index); // 标题行背景色为绿色
    cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); // 填充背景色
    cellStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER); // 文字水平居中
    cellStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER); // 文字垂直居中
    cellStyle.setBorderBottom(XSSFCellStyle.BORDER_THIN); // 底部边框实体线条
    cellStyle.setBorderTop(XSSFCellStyle.BORDER_THIN);  // 顶部边框实体线条
    cellStyle.setBorderLeft(XSSFCellStyle.BORDER_THIN);  // 左部边框实体线条
    cellStyle.setBorderRight(XSSFCellStyle.BORDER_THIN);  // 右部边框实体线条
    

    新版本

    CellStyle cellStyle = wb.createCellStyle();
    // XSSFCellStyle cellStyle = wb.createCellStyle();
    cellStyle.setFillForegroundColor(IndexedColors.LIME.index); // 标题行背景色为绿色
    cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 填充背景色
    cellStyle.setAlignment(HorizontalAlignment.CENTER); // 文字水平居中
    cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 文字垂直居中
    cellStyle.setBorderBottom(BorderStyle.THIN); // 底部边框实体线条
    cellStyle.setBorderTop(BorderStyle.THIN);  // 顶部边框实体线条
    cellStyle.setBorderLeft(BorderStyle.THIN);  // 左部边框实体线条
    cellStyle.setBorderRight(BorderStyle.THIN);  // 右部边框实体线条
    

    2.5 合并单元格

    旧版本

    Sheet sheet = workbook.createSheet("sheet1");
    // 起始行,结束行,起始列,结束列
    sheet.addMergedRegion(new CellRangeAddress(1, 1,(short) 0, (short) 0));
    

    新版本

    Sheet sheet = workbook.createSheet("sheet1");
    // 起始行,起始列,结束行,结束列
    sheet.addMergedRegion(new Region(1, (short) 0, 1,(short) 0));
    

    2.6 设置字体加粗

    旧版本

    Font font = workbook.createFont();
    // font.setBoldweight((short) 400);
    font.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
    font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
    font.setBoldweight(XSSFFont.BOLDWEIGHT_NORMAL);
    font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
    

    新版本

    Font font = workbook.createFont();
    font.setBold(true);
    

    2.7 设置图片属性

    旧版本

    // anchor主要用于设置图片的属性
    XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 255, 255, (short) i, rowNum + 1,
                     (short) i + 1, rowNum + 2);
    anchor.setAnchorType(3);
    // 插入图片
    patriarch.createPicture(anchor,workbook.addPicture(byteArrayOut.toByteArray(), 
                        ClientAnchor.MOVE_DONT_RESIZE));
    

    新版本

    // anchor主要用于设置图片的属性
    XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 255, 255, (short) i, rowNum + 1,
                     (short) i + 1, rowNum + 2);
    anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE));
    // 插入图片
    patriarch.createPicture(anchor,workbook.addPicture(byteArrayOut.toByteArray(), 
                        ClientAnchor.AnchorType.MOVE_DONT_RESIZE.value));
    

    2.8 小结

    poi版本升级问题产生报错汇总(后续待补充)

    poi3.17之前版本poi3.17+版本用途
    Cell.CELL_TYPE_STRINGCellType.STRING单元格数据格式判断
    HSSFCell.CELL_TYPE_NUMERICCellType.NUMERIC单元格数据格式判断
    CellStyle.ALIGN_CENTERHorizontalAlignment.CENTER单元格水平居中
    CellStyle.VERTICAL_CENTERVerticalAlignment.CENTER单元格垂直居中
    HSSFColor.GREY_25_PERCENT.indexIndexedColors.GREY_25_PERCENT.index设置图案颜色
    CellStyle.SOLID_FOREGROUNDFillPatternType.SOLID_FOREGROUND设置图案样式
    CellStyle.BORDER_THINBorderStyle.THIN边框
    ClientAnchor.MOVE_DONT_RESIZEAnchorType.MOVE_DONT_RESIZE.value单元格插入图片

    相关推荐

    数据分流写入Excel

    Poi版本升级优化

    StringTemplate实现Excel导出

    Poi模板技术

    SAX方式实现Excel导入

    DOM方式实现Excel导入

    Poi实现Excel导出

    EasyExcel实现Excel文件导入导出

    EasyPoi实现excel文件导入导出

    个人博客

    欢迎各位访问我的个人博客: https://www.crystalblog.xyz/

    备用地址: https://wang-qz.gitee.io/crystal-blog/

    展开全文
  • 解决poi版本冲突

    2020-11-05 18:21:32
    easyExcel最低依赖版本是3.17,系统中已经存在3.16版本,排除依赖有些类无法找到,导致jar包冲突无法共存。寻求解决方案时,看到[此篇文章]...


    背景

    由于业务需要,引入easyExcel。easyExcel最低依赖版本是3.17,系统中已经存在3.16版本,排除依赖有些类无法找到,导致jar包冲突无法共存。寻求解决方案时,实践可通过修改jar包路径达到目的。在此对过程做一下记录。

    参考文章

    资源下载:
    jarjar下载地址
    easyExcel仓库
    打包下载


    一、重新打包poi

    1.准备好需要的资源

    poi及jarjar

    2.创建rule.txt

    rule.txt

    3.rule.txt中写入文本

    rule org.apache.poi.**  com.customize.poi.@1
    

    3.验证能否修改包名

    3.17可以忽略,实践通过,详细用法可自行研究

    java -jar jarjar-1.3.jar strings  poi-3.17.jar
    

    在这里插入图片描述

    4.重新打包

    自行修改规则

    java -jar jarjar-1.3.jar process rule.txt poi-3.17.jar customize-poi-3.17.jar
    java -jar jarjar-1.3.jar process rule.txt poi-ooxml-3.17.jar customize-poi-ooxml-3.17.jar
    java -jar jarjar-1.3.jar process rule.txt poi-ooxml-schemas-3.17.jar customize-poi-schemas-3.17.jar
    

    生成新的jar包
    新生成的jar包

    5.打包到本地仓库

    mvn install:install-file -Dfile=customize-poi-3.17.jar -DgroupId=com.customize -DartifactId=poi -Dversion=3.17 -Dpackaging=jar
    
    mvn install:install-file -Dfile=customize-poi-ooxml-3.17.jar -DgroupId=com.customize -DartifactId=poi-ooxml -Dversion=3.17 -Dpackaging=jar
    
    mvn install:install-file -Dfile=customize-poi-schemas-3.17.jar -DgroupId=com.customize -DartifactId=poi-ooxml-schemas -Dversion=3.17 -Dpackaging=jar
    

    打包后
    打包到本地仓库

    二、重新编译easyExcel

    1.下载easyExcel源码

    注意easyExcel版本,导入IDE(笔者使用IDEA)
    在这里插入图片描述
    或者

    git clone https://github.com/alibaba/easyexcel.git
    git checkout -b dev2.2.6 v2.2.6
    

    2.修改pom文件中poi依赖

    <dependency>
       <groupId>com.customize</groupId>
       <artifactId>poi</artifactId>
       <version>3.17</version>
    </dependency>
    
    <dependency>
       <groupId>com.customize</groupId>
       <artifactId>poi-ooxml</artifactId>
       <version>3.17</version>
    </dependency>
    
    <dependency>
       <groupId>com.customize</groupId>
       <artifactId>poi-ooxml-schemas</artifactId>
       <version>3.17</version>
    </dependency>
    

    修改项目坐标

    <groupId>com.customize</groupId>
     <artifactId>easyexcel</artifactId>
     <version>2.2.6</version>
     <packaging>jar</packaging>
     <name>easyexcel</name>
    

    3.全局替换import

    在这里插入图片描述

    4.编译

    mvn clean install -DkispTests=true
    

    编译失败
    在这里插入图片描述
    加入依赖

    <dependency>
        <groupId>org.apache.xmlbeans</groupId>
        <artifactId>xmlbeans</artifactId>
        <version>2.3.0</version>
    </dependency>
    

    重新编译
    在这里插入图片描述

    三.使用

    1.项目中添加依赖

    此时easyExcel依赖为修改后的,可传至私服/安装到本地仓库

    <dependency>
          <groupId>com.customize</groupId>
          <artifactId>easyexcel</artifactId>
          <version>2.2.6</version>
      </dependency>
    

    依赖的pom

    <dependency>
         <groupId>com.customize</groupId>
         <artifactId>poi</artifactId>
         <version>3.17</version>
     </dependency>
    
     <dependency>
         <groupId>com.customize</groupId>
         <artifactId>poi-ooxml</artifactId>
         <version>3.17</version>
     </dependency>
    
     <dependency>
         <groupId>com.customize</groupId>
         <artifactId>poi-ooxml-schemas</artifactId>
         <version>3.17</version>
     </dependency>
    

    其余依赖(按需添加,可能已经存在,参考easyexcel原pom文件)

    <dependency>
         <groupId>cglib</groupId>
         <artifactId>cglib</artifactId>
         <version>3.1</version>
     </dependency>
    <dependency>
         <groupId>org.ehcache</groupId>
         <artifactId>ehcache</artifactId>
         <version>3.4.0</version>
     </dependency>
    

    2.测试easyExcel功能

    不出意外,此时可正常同时两个版本pom共存

    展开全文
  • 项目之前用的poi版本是3.9,后来使用easyexcel的时候,出现某些类找不到,这是因为poi.jar包版本冲突导致的,maven会自动使用最高级的版本,而easyexcel是3.1.7,将项目依赖的poi升级到4.1.2就好了。 <poi....
  • poi版本不兼容问题解决

    千次阅读 2020-04-20 13:48:25
    问题的起因:导入excel内存溢出然后使用了一个现成的车轮子com.monitorjbl.xlsx-streamer-2.0.0.jar...产生兼容问题的原因:由于我们公司项目中使用了org.apache.poi-3.9.jar而com.monitorjbl.xlsx-streamer-2....
  • Java使用POI做excel导出,poi版本:3.17

    千次阅读 2018-12-06 14:35:09
    1、在pom.xml中导入相关依赖 ...org.apache.poi&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;poi&amp;lt;/artifactId&amp;gt; &amp;lt;version&amp;gt;3.1
  • poi版本升级(3.13到4.0.1)的那些坑

    千次阅读 2020-03-09 11:13:49
    前景:由于项目需要使用到poi-tl的框架,但是poi-tl最低的要求是poi3.16以上版本,但是项目的poi使用的是3.13,太旧了,索性一次性升级到了4.01版本; 变更jar包的版本,或多或少都是会有一些冲突的,如下代码: 1....
  • 原始版本代码入下。 if (POIFSFileSystem.hasPOIFSHeader(inputstream)) { book = new HSSFWorkbook(inputstream); isXSSFWorkbook = false; }else if (POIXMLDocument.hasOOXMLHeader(i...
  • 使用poi版本不同导致报错

    千次阅读 2016-08-10 09:54:14
    近日在做poi解析word的时候遇到一个很奇葩的问题,在本地环境测试都没有问题,当部署到测试环境(Linux系统,weblogic10.3.6服务器)一直解析不了,报找不到方法。 具体错误如下: Caused by: java.lang....
  • org.apache.poi版本问题

    千次阅读 2018-11-09 19:00:00
    问题描述: 今天跑一段历史代码,发现不能启动,抛出java.lang.NoSuchFieldError: RETURN_...把org.apache.poi版本更改为3.11,之前为3.17. 参考文章 转载于:https://www.cnblogs.com/donfaquir/p/9936684.html...
  • private static JSONArray POIReadXLSX(InputStream in){ JSONArray list = new JSONArray(); XSSFWorkbook xwb; try { xwb = new XSSFWorkbook(in);... XSSFSheet sheet = xwb.getSheetAt(0);...
  • 使用unitiles+dbunit 2.4.8,由于我的测试数据使用xls文件,所以需要用到poi库,但是dbunit只支持poi 3.2版本的,高版本时会报: [quote]java.lang.NoSuchMethodError: org.apache.poi.hssf.usermodel.HSSFDateUtil....
  • 使用较新poi版本实现word 转 html

    千次阅读 2018-10-16 17:04:21
    compile “org.apache.poi:poi-scratchpad:3.17” compile “org.apache.poi:poi-ooxml:3.17” compile “fr.opensagres.xdocreport:fr.opensagres.poi.xwpf.converter.core:2.0.1” compile “fr.opensagres....
  • 由于用到数据库导出EXCEL,下载了POI3.7来使用,结果放到系统中总是提示java.lang.NoClassDefFoundError: org/apache/poi/ss/usermodel/RichTextString查了半天才明白。老版本cell.setCellValu
  • 1.最近的项目中使用到了Drools作为规则引擎,今天在开发决策表的导入功能时(xls...3.首先我的第一反应就是应该是jar包冲突,我当时用的drools版本是6.4,poi是3.9: 4.后来经过多次尝试,选择drools为7.0版本
  • 解析的公式单元格的时候发现cellType是null,characters方法只能获取公式不能获取已经计算出的公式值
  • 最近使用EasyExcel写导入导出Excel,需要POI版本是3.17,之前是3.9,必须升级jar包,升级之后发现很多代码报错,需要修改调整,以下用于记录调整的代码。 颜色定义变化 旧版本 : HSSFColor.BLACK.index 新版...
  • apache poi版本对应jdk

    千次阅读 2020-09-09 09:33:56
    apache poi版本对应jdk 最近因为poi和jdk的版本对应问题,遇到了一些糟心的事。在此先记录一下吧,以免以后遇到 之前一直没找到,百度了半天都没有找到相关的说明,好在在官网找到了这个(英文不好,找起来也...
  • 笔者在实际开发中,遇到了poi版本的问题,老项目一枚,存在poi3.8和easypoi3.0.1(其实老项目中就存在版本冲突问题了) 多处遇到了导入导出的功能,本着能使用高版本稳定版本就不用老版本的想法(老是因为照顾低版本,...
  • 2018高德poi 2018版本poi

    2020-06-19 14:13:32
    2005、2006、2007、2008、2009、2010、2011、2012、2013、2014、2015、2016、2017、20182019、2020最专业的科研poi数据
  • poi3.17版本jar包

    2021-02-04 16:00:43
    poi开源jar包3.17版本,解压后的jar包导入java项目后即可使用。
  • POI

    万次阅读 2021-01-17 17:10:20
    Poi(适合小数据量) Apache POI 官网:https://poi.apache.org/ POI是Apache软件基金会的,POI为“Poor Obfuscation Implementation”的首字母缩写,意为“简洁版的模糊实现”。 所以POI的主要功能是可以用Java操作...
  • poi3.14版本jar包

    2020-10-17 22:02:41
    poi 3.14需要的jar包 poi 3.14需要的jar包 poi 3.14需要的jar包 poi 3.14需要的jar包
  • 2005、2006、2007、2008、2009、2010、2011、2012、2013、2014、2015、2016、2017、20182019、2020最专业的科研poi数据
  • poi的3.17版本问题

    万次阅读 2020-04-01 12:01:32
    网上很多版本对于poi中样式中样式设置都是poi之前的操作,在poi3.17版本中并不能直接使用 (1)单元格样式 在poi导出设置单元格样式的居中问题时候,网上大部分的操作代码如下: XSSFCellStyle cellStyle = wb....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 24,643
精华内容 9,857
关键字:

poi版本