有什么办法知道CellStyle已经存在于工作簿(重用)使用POI或仅复制Celstyle obj不参考

我想写一些logging到Excel中,但我知道XSSFWorkbook中的最大单元格样式是XSSFWorkbooklogging超过64000,并考虑我想要将新的单元格样式应用于每个单元格,或者我将克隆已有的单元格样式。

即使克隆我需要采取默认的单元格样式workbook.createCellStyle(); 但是这超出了64001logging导致java.lang.IllegalStateException: The maximum number of cell styles was exceeded.

所以反正POI中已经知道已经有特定的单元格样式,并利用它或者需要克隆/创build默认的单元格样式和克隆。

克隆的原因是:有时候列/行的cellstyle现有的excel的cellstyle可能会有所不同,所以我们采取默认的cell style,并将col&row&cell cellstyles克隆到它。

即使我试图添加一个默认的样式到地图map.put("defStyle",workbook.createCellStyle();)但这不会克隆正确,因为它会改变第一次尝试克隆,因为It wont get the Object it will copy the reference甚至对象克隆也不可能在这里,因为cellstyle不实现可cloneable interface

一般来说,创build尽可能多的单元格样式并不需要超过可能的单元格样式的最大数量。 要根据内容格式化单元格,可以使用条件格式。 也可以使用格式化行(例如奇/偶行不同)条件格式化。 也为列。

所以通常不应该使用单元格样式来格式化每个单元格或大量的单元格。 相反,应该创build更less的单元格样式,然后将其用作默认的单元格样式,或者在单个情况下,如果条件格式化将不可行。

在我的例子中,我有一个默认的单元格样式的所有单元格和单行单元格样式的第一行(即使这可以使用条件格式)。

为了保持默认的单元格样式适用于所有列后,它必须适用于所有与apache poi新创build的单元格。 为此我提供了一个方法getPreferredCellStyle(Cell cell)Excel自身将自动将列(或行)单元格样式应用于新的已填充单元格。

如果还是有必要格式化单个单元格,那么应该使用CellUtil 。 这提供了“处理样式”的各种方法,允许您在需要的时候创buildCellStyles。当您将样式更改应用到单元格时,代码将尝试查看样式是否已经存在以满足您的需求。它会创build一个新的样式,这是为了防止创build太多的样式,在Excel支持的样式数上有一个上限。 请参阅我的示例中的注释。

 import java.io.*; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.*; import org.apache.poi.ss.util.CellUtil; import java.util.Map; import java.util.HashMap; public class CarefulCreateCellStyles { public CellStyle getPreferredCellStyle(Cell cell) { // a method to get the preferred cell style for a cell // this is either the already applied cell style // or if that not present, then the row style (default cell style for this row) // or if that not present, then the column style (default cell style for this column) CellStyle cellStyle = cell.getCellStyle(); if (cellStyle.getIndex() == 0) cellStyle = cell.getRow().getRowStyle(); if (cellStyle == null) cellStyle = cell.getSheet().getColumnStyle(cell.getColumnIndex()); if (cellStyle == null) cellStyle = cell.getCellStyle(); return cellStyle; } public CarefulCreateCellStyles() throws Exception { Workbook workbook = new XSSFWorkbook(); // at first we are creating needed fonts Font defaultFont = workbook.createFont(); defaultFont.setFontName("Arial"); defaultFont.setFontHeightInPoints((short)14); Font specialfont = workbook.createFont(); specialfont.setFontName("Courier New"); specialfont.setFontHeightInPoints((short)18); specialfont.setBold(true); // now we are creating a default cell style which will then be applied to all cells CellStyle defaultCellStyle = workbook.createCellStyle(); defaultCellStyle.setFont(defaultFont); // maybe sone rows need their own default cell style CellStyle aRowCellStyle = workbook.createCellStyle(); aRowCellStyle.cloneStyleFrom(defaultCellStyle); aRowCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); aRowCellStyle.setFillForegroundColor((short)3); Sheet sheet = workbook.createSheet("Sheet1"); // apply default cell style as column style to all coluumns org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol cTCol = ((XSSFSheet)sheet).getCTWorksheet().getColsArray(0).addNewCol(); cTCol.setMin(1); cTCol.setMax(workbook.getSpreadsheetVersion().getLastColumnIndex()); cTCol.setWidth(20 + 0.7109375); cTCol.setStyle(defaultCellStyle.getIndex()); // creating cells Row row = sheet.createRow(0); row.setRowStyle(aRowCellStyle); Cell cell = null; for (int c = 0; c < 3; c++) { cell = CellUtil.createCell(row, c, "Header " + (c+1)); // we get the preferred cell style for each cell we are creating cell.setCellStyle(getPreferredCellStyle(cell)); } System.out.println(workbook.getNumCellStyles()); // 3 = 0(default) and 2 just created row = sheet.createRow(1); cell = CellUtil.createCell(row, 0, "centered"); cell.setCellStyle(getPreferredCellStyle(cell)); CellUtil.setAlignment(cell, HorizontalAlignment.CENTER); System.out.println(workbook.getNumCellStyles()); // 4 = 0 and 3 just created cell = CellUtil.createCell(row, 1, "bordered"); cell.setCellStyle(getPreferredCellStyle(cell)); Map<String, Object> properties = new HashMap<String, Object>(); properties.put(CellUtil.BORDER_LEFT, BorderStyle.THICK); properties.put(CellUtil.BORDER_RIGHT, BorderStyle.THICK); properties.put(CellUtil.BORDER_TOP, BorderStyle.THICK); properties.put(CellUtil.BORDER_BOTTOM, BorderStyle.THICK); CellUtil.setCellStyleProperties(cell, properties); System.out.println(workbook.getNumCellStyles()); // 5 = 0 and 4 just created cell = CellUtil.createCell(row, 2, "other font"); cell.setCellStyle(getPreferredCellStyle(cell)); CellUtil.setFont(cell, specialfont); System.out.println(workbook.getNumCellStyles()); // 6 = 0 and 5 just created // until now we have always created new cell styles. but from now on CellUtil will use // already present cell styles if they matching the needed properties. row = sheet.createRow(2); cell = CellUtil.createCell(row, 0, "bordered"); cell.setCellStyle(getPreferredCellStyle(cell)); properties = new HashMap<String, Object>(); properties.put(CellUtil.BORDER_LEFT, BorderStyle.THICK); properties.put(CellUtil.BORDER_RIGHT, BorderStyle.THICK); properties.put(CellUtil.BORDER_TOP, BorderStyle.THICK); properties.put(CellUtil.BORDER_BOTTOM, BorderStyle.THICK); CellUtil.setCellStyleProperties(cell, properties); System.out.println(workbook.getNumCellStyles()); // 6 = nothing new created cell = CellUtil.createCell(row, 1, "other font"); cell.setCellStyle(getPreferredCellStyle(cell)); CellUtil.setFont(cell, specialfont); System.out.println(workbook.getNumCellStyles()); // 6 = nothing new created cell = CellUtil.createCell(row, 2, "centered"); cell.setCellStyle(getPreferredCellStyle(cell)); CellUtil.setAlignment(cell, HorizontalAlignment.CENTER); System.out.println(workbook.getNumCellStyles()); // 6 = nothing new created workbook.write(new FileOutputStream("CarefulCreateCellStyles.xlsx")); workbook.close(); } public static void main(String[] args) throws Exception { CarefulCreateCellStyles carefulCreateCellStyles = new CarefulCreateCellStyles(); } } 

不容易。 我提前定义了需要的样式,然后将它们显式应用到每个单元格,而不是仅为每个单元格创build新的样式。 请注意,我不包含那些预定义样式的边框,只包括字体,颜色和填充。 对于边框,稍后我将其绘制到电子表格中以简化代码。