Pra*_*mar 5 java excel apache-poi
我想将一些记录写入 excel 但我知道最大单元格样式XSSFWorkbook是 64000。但是记录超过 64000 并考虑我想cellstyle对每个单元格应用新的,否则我将使用现有的单元格样式进行克隆。
即使要克隆,我也需要采用默认的单元格样式, workbook.createCellStyle();但这超过了 64001 条记录,导致java.lang.IllegalStateException: The maximum number of cell styles was exceeded..
那么无论如何在 POI 中是否知道已经存在特定的单元格样式并利用它或何时需要克隆/创建默认单元格样式和克隆。
克隆的原因是:有时列/行cellstyle和 现有引用的 excel 单元格样式可能不同,因此我采用默认单元格样式并将 col & row & cell 克隆cellstyles到它。
即使我尝试向地图添加默认样式,map.put("defStyle",workbook.createCellStyle();)但这不会正确克隆,因为它会在第一次克隆尝试时发生变化,因为It wont get the Object it will copy the reference即使对象克隆在这里也不可能,因为 cellstyle 没有实现cloneable interface.
通常,没有必要创建超过可能的单元格样式的最大数量的单元格样式。要根据其内容格式化单元格,可以使用条件格式。也可以使用条件格式来格式化行(例如不同的奇数/偶数行)。也用于列。
所以通常不是每个单元格或大量单元格都应该使用单元格样式进行格式化。相反,应该创建较少数量的单元格样式,然后将其用作默认单元格样式或在单个情况下,如果条件格式确实不可能。
在我的示例中,我为所有单元格设置了默认单元格样式,并为第一行设置了单行单元格样式(即使这可以使用条件格式来实现)。
要在将默认单元格样式应用于所有列后保持其正常工作,必须将其应用于所有具有apache poi新创建的单元格。为此,我提供了一种方法getPreferredCellStyle(Cell cell)。Excel本身会自动将列(或行)单元格样式应用于新填充的单元格。
如果仍然需要对单个单元格进行不同的格式设置,则应为此使用CellUtil。这提供了“处理样式的各种方法允许您根据需要创建 CellStyles。当您将样式更改应用于单元格时,代码将尝试查看是否已经存在满足您需要的样式。如果没有,则它将创建一个新样式。这是为了防止创建太多样式。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 columns
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
FileOutputStream out = new FileOutputStream("CarefulCreateCellStyles.xlsx");
workbook.write(out);
out.close();
workbook.close();
}
public static void main(String[] args) throws Exception {
CarefulCreateCellStyles carefulCreateCellStyles = new CarefulCreateCellStyles();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7936 次 |
| 最近记录: |