我正在使用apache-poi动态创建一个新的xlsx文件 . 任何列都可以包含不同的值类型(数字,字符串,布尔值,...) . 在将数据插入poi文档时,我根据数据类型设置CellStyles:
public final XSSFCellStyle cellStyleString;
public final XSSFCellStyle cellStyleNumber;
public final XSSFCellStyle cellStyleDate;
public final XSSFCellStyle cellStyleHeader;
这是我的 Headers 行的样子:
| | | | Shared Header |
| H1| H2| H3|SH1|SH2|SH3|SH4|
有“简单” Headers 和“共享 Headers ”,其中包含“子 Headers ” . 共享标头位于合并的单元中 .
不,我想在列 SH1
处设置左边框,在列 SH4
处设置右边框以强调分组 . 但是,由于任何列都可以包含所有单元格的混合,似乎我必须创建像CellStyles一样
public final XSSFCellStyle cellStyleString;
public final XSSFCellStyle cellStyleStringBorderLeft;
public final XSSFCellStyle cellStyleStringBorderRight;
//and so on for the other styles...
此外,可能有嵌套的共享 Headers ,我想通过不同的边框大小区分 . 所以我需要类似的东西
public final XSSFCellStyle cellStyleString;
public final XSSFCellStyle cellStyleStringBorderLeftThickLine;
public final XSSFCellStyle cellStyleStringBorderRightThickLine;
public final XSSFCellStyle cellStyleStringBorderLeftThinLine;
public final XSSFCellStyle cellStyleStringBorderRightThinLine;
//and so on for the other styles...
无论现有样式如何,是否有更优雅的方式来设置列的边框?
Edit
虽然我更喜欢干净简单的方法,并且为了最大限度地减少创建的样式的数量,我在HSSFOptimiser上删除了重复的单元格样式 . 我不知道那堂课 . 即使我更喜欢避免这个实用程序,它也适合这个问题,值得在这里提到 .
3 回答
我即将结束对POI的增强,这将使您可以使用其特定样式填充值,然后在它们周围绘制边框,而无需手动创建所有必需的样式 . 在平均时间,有一种方法可以使用
CellUtil.setCellStyleProperties()
. 这允许您向单元格已存在的CellStyle
添加一组属性 .来自HSSF / XSSF的POI快速指南:
这允许您基本上填写电子表格,然后一次绘制一个单元格的边框 . 请注意,如果所有边框都相似(全部为THIN),那么这将适用于整个范围 . 但是,如果要在表格外部绘制MEDIUM边框,则必须创建一些其他属性集 . 请注意,您不必对电子表格中已有的行和单元格使用
createRow()
和createCell()
. 这将解决合并的单元格 .注意:
CellUtil.setCellStyleProperties()
出现在POI 3.14中,允许您在一次拍摄中添加多个单元格属性,从而避免创建多个未使用的样式 . 较旧的CellUtil.setCellStyleProperty()
一次设置一个属性,并且作为意外结果,在电子表格中创建中间的CellStyle
对象,结果从未被使用过 . 这可能是较大的纸张中的问题 .编辑:
PropertyTemplate
是POI 3.15中添加的新对象,它允许您为单元格定义一组边框并将其标记到要应用它的任何图纸上 . 此对象类似于创建预打印表单以覆盖数据 . 有关如何使用PropertyTemplate
的更多信息,请参阅POI电子表格快速指南 .正如您已经提到的,创建成千上万个类似的单元格样式对象并不好 . 在我的项目中,我创建了一个简单的“样式助手”类,其中包含一个映射,它知道所有现有的样式实例
参数ExcelCellAlign是一个简单的枚举,它封装了CellStyle.ALIGN_LEFT,CellStyle.ALIGN_RIGHT,...的值.ExcelCellBorder与Align类似 . 只需隐藏值:-) ExcelCellFormat是一个枚举,它包含用于强化值的默认模式 .
我希望这对你自己的实施来说是个好的开始 . 如果有什么不清楚,请随时询问
编辑:
那么如何利用POI对象的散列进行缓存并跟踪装饰对象 . 另一个未使用的CellStyles将被垃圾收集丢弃 .
这是我们的缓存:
还有我们自己的CellStyle类
现在为了避免创建新对象,我们编写了一个小函数
然后我们可以像这样自己创建单元格:
如果hashCode对于MyCellStyle对象的相同属性不是唯一的,我们可能必须覆盖hashCode函数:
并在每个装饰函数中添加样式值:
=======================
原版的:
我喜欢创建装饰方法,将单元格的某个方面添加到单元格样式中 . 所以首先你创建你的基本风格
并创建装饰器方法来创建某种样式
现在,如果你想避免创建新对象,你仍然需要保留在自己的变量中的cellStyles,你将无法避免这种情况,但根据我的经验,如果你只是简单地装饰你的细胞,那么性能就足够了
如果你用很多样式进行装饰,那么创建自己的CellStyle类是有意义的
然后,您可以以更易读的方式构建您的样式:
未经测试,但我希望它有所帮助 .