POI导出excel

您所在的位置:网站首页 excel列宽不一样 POI导出excel

POI导出excel

2023-12-20 23:37| 来源: 网络整理| 查看: 265

1. 前言

poi框架可以支持我们在java代码中, 将数据导出成excel , 在上一篇 如何使用POI导出excel表格,以及处理浏览器无法识别下载文件的问题 中已经详细的进行了介绍 , 但是实际开发中, 往往还需要设置excel字体,颜色,行高,列宽等属性, 有时候还需要锁住单元格, 防止别人讲数据随意篡改.

废话不多说, 直接上代码

2. 锁住单元格

导出excel , 自然就有导入excel 了, 比如导出一些数据出来, 修改一些再导入进去, 但是这时, 一些基本信息我们不希望用户随意去修改, 这里就用到了excel的锁 这里写图片描述

sheet.protectSheet(密码)

代码:

// 创建Excel文件 HSSFWorkbook workbook = new HSSFWorkbook(); HSSFSheet sheet = workbook.createSheet(DateUtils.getDate("yyyyMMdd")); //锁定sheet sheet.protectSheet("zgd");

这样的话, 这个sheet都会被锁定

但是我们又希望开放一些单元格可以修改 , 这个时候就要细粒度的进行设置了 创建一个cellStyle:

CellStyle unlockCell = workbook.createCellStyle(); unlockCell.setLocked(false);

然后在我们不需要锁定的单元格上, 给它这个 cellStyle

// 设置dataRow这一行的第i个单元格不锁定 dataRow.getCell(i).setCellStyle(unlockCell); 3. 设置列宽

在锁定了sheet之后, 会发现一个问题, 就是列宽都不能改变了

这个时候没办法, 只能自己设置列宽了, 现在网上找到的设置列宽的方法有以下几个:

1.自适应列宽度: sheet.autoSizeColumn(1);sheet.autoSizeColumn(1, true); 这两种方式都是自适应列宽度,但是注意这个方法在后边的版本才提供,poi的版本不要太老。 注意:第一个方法在合并单元格的的单元格并不好使,必须用第二个方法。

经过测试,这种自适应的api在遇到行数多一点的数据的时候,就会耗费大量的时间,1000行花了2分钟!!!所以尽量不要用

sheet.trackAllColumnsForAutoSizing(); sheet.autoSizeColumn(i);

而且这两个方法对英文数字还好, 对中文支持的并不好: 见图 这里写图片描述

2.用数组将大概的宽度设置好,手动set宽度 int[] width = {xxx,xxx}; for循环 sheet.setColumnWidth(i,width[i]); 3.自己根据一列数据中的最长的字符串长度设置宽度

所以还是得自己费心费力去diy :

判断这一列的最长字符串,然后 int length = str.getBytes().length; sheet.setColumnWidth((short)列数,(short)(length*256));

这里经过我反复尝试,我个人觉得把最大宽度限制在10000到15000左右是比较合适的, 然后剩下的就交给excel的自动换行

像我这里有很多行的数据, 不知道哪一行的内容最长, 这里简单提供两种思路(方法是很多的, 能达到目的就行): 1. 用一个Map, key是指具体哪一列, List中放的是每行的这一列的内容的长度 , 每遍历一行的一列, 就map.put(i, list.add(length)), 然后用Collections.max(map.get(i))来获取第i列的最长的长度 2. 还是一样,用一个map: `Map,key是指具体哪一列,value是每行的这一列的内容的长度, map.put(i,Math.max(length,map.get(i))),来确保map中的key对应的value永远是目前的最大的长度.

我这里使用的第二种: 设置自动换行后,不要设置固定的行高,否则超出的部分也会被遮住不显示

// 创建Excel文件 HSSFWorkbook workbook = new HSSFWorkbook(); HSSFSheet sheet = workbook.createSheet("sheet"); //设置样式 CellStyle blackStyle = workbook.createCellStyle(); //自动换行*重要* blackStyle.setWrapText(true); //存储最大列宽 Map maxWidth = new HashMap(); // 标题行 HSSFRow titleRow = sheet.createRow(0); titleRow.setHeightInPoints(20);//目的是想把行高设置成20px titleRow.createCell(0).setCellValue("sku编号"); titleRow.createCell(1).setCellValue("商品标题"); titleRow.createCell(2).setCellValue("商品名"); // 初始化标题的列宽,字体 for (int i= 0; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3