EasyPOI 根据模板导出excel时,无法自适应行高得解决方案记录

您所在的位置:网站首页 excel怎么根据内容自动调整行高 EasyPOI 根据模板导出excel时,无法自适应行高得解决方案记录

EasyPOI 根据模板导出excel时,无法自适应行高得解决方案记录

2024-02-03 12:18| 来源: 网络整理| 查看: 265

目录 EasyPOI 根据模板导出excel时,无法自适应行高得解决方案记录首先说一下问题得场景第一步第二步第三步第四步第五步第六步第七步 (就是这个方法!)

EasyPOI 根据模板导出excel时,无法自适应行高得解决方案记录 首先说一下问题得场景 我这里时用来做PDF 得生成得 ,先使用Excel 模板生成excel,再将excel流转为pdf,但是问题也就产生了,就是如果行高不自适应得话会导致内容得丢失。这点我做了好多的处理也不好使,最先想到的是使用Excel的模板设置 ,但是不会生效,很遗憾。或者通过EasyPOI来设置Style,也没有设置行高的选项(我是使用模板进行转换的)。所以也是没有办法了,常规通用的方法已经不能实现需求了,只能是查看EasyPOI源码来哪个地方没有自适应,并对其做相应的更改。上一波模板。在这里插入图片描述这里的这三个字段可能会过长需要换行并且调整行高,都是字符串String类型的数据。 第一步

在这里插入图片描述

第二步

在这里插入图片描述

第三步

在这里插入图片描述

到这里就发现代码比较复杂了,但是不要慌,很容易我们就能找到对模板进行赋值操作的是这个方法parseTemplate(wb.getSheetAt(i),map,params.isColForEash()),所以我们继续点,嘿嘿! 第四步

在这里插入图片描述

这一步很清晰的知道赋值代码是setValueForCellByMap(row.getCell(i),map); 第五步

在这里插入图片描述

这里我们看到有好几处对单元格进行赋值,经过我测试debug发现上边的都不是对循环进行赋值的地方只有下边的代码是 //判断foreach 这种方法 if (oldString != null && oldString.contains(FOREACH)) { addListDataToExcel(cell, map, oldString.trim()); }

所以继续点。

第六步

在这里插入图片描述

我们能看到两处地方使用了这个 方法,我们点进去看看。 第七步 (就是这个方法!) setForEeachRowCellValue(isCreate, cell.getRow(), cell.getColumnIndex(), t, columns, map,rowspan, colspan, mergedRegionHelper) private void setForEeachRowCellValue(boolean isCreate, Row row, int columnIndex, Object t, List columns, Map map, int rowspan, int colspan, MergedRegionHelper mergedRegionHelper) throws Exception { //所有的cell创建一遍 for (int i = 0; i if (row.getCell(j) == null) { row.createCell(j); CellStyle style = row.getRowNum() % 2 == 0 ? getStyles(false, size >= j - columnIndex ? null : columns.get(j - columnIndex)) : getStyles(true, size >= j - columnIndex ? null : columns.get(j - columnIndex)); //返回的styler不为空时才使用,否则使用Excel设置的,更加推荐Excel设置的样式 if (style != null) { row.getCell(j).setCellStyle(style); } } } if (i int ci = columnIndex;//cell的序号 short high=columns.get(0).getHeight(); int n=k; while (n>0) { if ( columns.get(n * colspan).getHeight()==0) { n--; } else { high= columns.get(n * colspan).getHeight(); break; } } row.setHeight(high); for (int i = 0; i continue; } if (StringUtils.isEmpty(params.getName()) && StringUtils.isEmpty(params.getConstValue())) { row.getCell(ci).setCellStyle(params.getCellStyle()); ci = ci + params.getColspan(); continue; } String val = null; Object obj = null; //是不是常量 if (StringUtils.isEmpty(params.getName())) { val = params.getConstValue(); } else { String tempStr = new String(params.getName()); if (isNumber(tempStr)) { isNumber = true; tempStr = tempStr.replaceFirst(NUMBER_SYMBOL, ""); } map.put(teplateParams.getTempParams(), t); obj = eval(tempStr, map); val = obj.toString(); } if (obj != null && obj instanceof ImageEntity) { ImageEntity img = (ImageEntity)obj; row.getCell(ci).setCellValue(""); createImageCell(row.getCell(ci),img.getHeight(),img.getUrl(),img.getData()); }else if (isNumber && StringUtils.isNotEmpty(val)) { row.getCell(ci).setCellValue(Double.parseDouble(val)); row.getCell(ci).setCellType(Cell.CELL_TYPE_NUMERIC); } else { try { row.getCell(ci).setCellValue(val); } catch (Exception e) { LOGGER.error(e.getMessage(), e); } } row.getCell(ci).setCellStyle(params.getCellStyle()); // plq modify at 2017-11-13 //判断这个属性是不是需要统计 if (params.isNeedSum()) { templateSumHandler.addValueOfKey(params.getName(), val); } //如果合并单元格,就把这个单元格的样式和之前的保持一致 setMergedRegionStyle(row, ci, params); //合并对应单元格 if ((params.getRowspan() != 1 || params.getColspan() != 1) && !mergedRegionHelper.isMergedRegion(row.getRowNum() + 1, ci)) { PoiMergeCellUtil.addMergedRegion(row.getSheet(), row.getRowNum(), row.getRowNum() + params.getRowspan() - 1, ci, ci + params.getColspan() - 1); } ci = ci + params.getColspan(); } row = row.getSheet().getRow(row.getRowNum() + 1); } } 通过查看前面代码的模式可以看出,或者可以debug得出这里是对字符串赋值的地方。 在这里插入图片描述上边那两个是图片和数字赋值的地方。所以我们需要在这里进行更改就好了。进入细节。大家要注意奥!上一波我得代码。方便大家复制参考我上代码,不是图片 private void setForEeachRowCellValue(boolean isCreate, Row row, int columnIndex, Object t, List columns, Map map, int rowspan, int colspan, MergedRegionHelper mergedRegionHelper) throws Exception { //所有的cell创建一遍 for (int i = 0; i if (row.getCell(j) == null) { row.createCell(j); CellStyle style = row.getRowNum() % 2 == 0 ? getStyles(false, size >= j - columnIndex ? null : columns.get(j - columnIndex)) : getStyles(true, size >= j - columnIndex ? null : columns.get(j - columnIndex)); //返回的styler不为空时才使用,否则使用Excel设置的,更加推荐Excel设置的样式 if (style != null) { row.getCell(j).setCellStyle(style); } } } if (i int ci = columnIndex;//cell的序号 short high=columns.get(0).getHeight(); int n=k; while (n>0) { if ( columns.get(n * colspan).getHeight()==0) { n--; } else { high= columns.get(n * colspan).getHeight(); break; } } row.setHeight(high); for (int i = 0; i continue; } if (StringUtils.isEmpty(params.getName()) && StringUtils.isEmpty(params.getConstValue())) { row.getCell(ci).setCellStyle(params.getCellStyle()); ci = ci + params.getColspan(); continue; } String val = null; Object obj = null; //是不是常量 if (StringUtils.isEmpty(params.getName())) { val = params.getConstValue(); } else { String tempStr = new String(params.getName()); if (isNumber(tempStr)) { isNumber = true; tempStr = tempStr.replaceFirst(NUMBER_SYMBOL, ""); } map.put(teplateParams.getTempParams(), t); obj = eval(tempStr, map); val = obj.toString(); } if (obj != null && obj instanceof ImageEntity) { ImageEntity img = (ImageEntity)obj; row.getCell(ci).setCellValue(""); createImageCell(row.getCell(ci),img.getHeight(),img.getUrl(),img.getData()); }else if (isNumber && StringUtils.isNotEmpty(val)) { row.getCell(ci).setCellValue(Double.parseDouble(val)); row.getCell(ci).setCellType(Cell.CELL_TYPE_NUMERIC); } else { try { int valLength = 0; Map cellMap = isCombineCell(cellRangeAddressList,row.getCell(ci),row.getSheet()); // 合并的单元格列数 int mergeCellCount = ObjectUtils.isEmpty(cellMap.get("mergedCol"))? 0 : (Integer) cellMap.get("mergedCol"); char [] strs = val.toCharArray(); // 如果是汉字则为 两个字符 for (char e : strs) { if(String.valueOf(e).matches("[\u4e00-\u9fa5]")){ valLength = valLength +2; }else { valLength = valLength + 1; } } // 获取单元格宽 int width = (row.getSheet().getColumnWidth(row.getCell(ci).getColumnIndex()) / 256) +1 ; // 获取单元格高度 BigDecimal height = new BigDecimal(row.getHeight()).divide(new BigDecimal(256)); // 如果该单元格被合并了 if(mergeCellCount > 0){ // 获取合并单元格宽度 for(int j = 1 ;j row.setHeight(new BigDecimal(256).multiply(height) .multiply(new BigDecimal((valLength / width) + 1)).shortValue()); } row.getCell(ci).setCellValue(val); } catch (Exception e) { LOGGER.error(e.getMessage(), e); } } row.getCell(ci).setCellStyle(params.getCellStyle()); // plq modify at 2017-11-13 //判断这个属性是不是需要统计 if (params.isNeedSum()) { templateSumHandler.addValueOfKey(params.getName(), val); } //如果合并单元格,就把这个单元格的样式和之前的保持一致 setMergedRegionStyle(row, ci, params); //合并对应单元格 if ((params.getRowspan() != 1 || params.getColspan() != 1) && !mergedRegionHelper.isMergedRegion(row.getRowNum() + 1, ci)) { PoiMergeCellUtil.addMergedRegion(row.getSheet(), row.getRowNum(), row.getRowNum() + params.getRowspan() - 1, ci, ci + params.getColspan() - 1); } ci = ci + params.getColspan(); } row = row.getSheet().getRow(row.getRowNum() + 1); } }

这里解释一下代码。先说几个问题。

首先是第一个问题就是根据什么来调整行高?当然是根据文字的长度,但是这里有一个问题就是中文字符的宽度和数字和英文字符的长度不是一样的长度,我们这里假设一个中文字符宽度等于两个其他字符的宽度。第二我们通过POI方法row.getSheet().getColumnWidth(row.getCell(ci).getColumnIndex()来获取单元格宽度是一个什么样数字这里我debug到这里的时候发现是一个很大数值,这个数值除以256 等与一个字符的长度!!!!! 这是重点哦,这样我们才能完成后边的计算。第三如果我们合并了单元格,但是POI获取宽度的方法只会获取第一个单元格的宽度,并不是实际单元格的长度。因此我们需要考虑合并单元格的问题。先上两个方法再解释。 /** * 判断cell是否为合并单元格,是的话返回合并行数和列数(只要在合并区域中的cell就会返回合同行列数,但只有左上角第一个有数据) * @param listCombineCell 上面获取的合并区域列表 * @param cell * @param sheet * @return * @throws Exception */ public static Map isCombineCell(List listCombineCell,Cell cell,Sheet sheet) throws Exception{ int firstC = 0; int lastC = 0; int firstR = 0; int lastR = 0; String cellValue = null; Boolean flag=false; int mergedRow=0; int mergedCol=0; Map result=new HashMap(); result.put("flag",flag); for(CellRangeAddress ca:listCombineCell) { //获得合并单元格的起始行, 结束行, 起始列, 结束列 firstC = ca.getFirstColumn(); lastC = ca.getLastColumn(); firstR = ca.getFirstRow(); lastR = ca.getLastRow(); //判断cell是否在合并区域之内,在的话返回true和合并行列数 if(cell.getRowIndex() >= firstR && cell.getRowIndex() flag=true; mergedRow=lastR-firstR+1; mergedCol=lastC-firstC+1; result.put("flag",true); result.put("mergedRow",mergedRow); result.put("mergedCol",mergedCol); break; } } } return result; } //获取合并单元格集合 public static List getCombineCellList(Sheet sheet) { List list = new ArrayList(); //获得一个 sheet 中合并单元格的数量 int sheetmergerCount = sheet.getNumMergedRegions(); //遍历所有的合并单元格 for(int i = 0; i


【本文地址】


今日新闻


推荐新闻


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