当前位置: 首页 > 面试题库 >

是否有任何方法可以知道使用POI在工作簿中已经存在CellStyle(以便重用)或仅复制Celstyle obj而不引用

令狐功
2023-03-14
问题内容

我想在excel中写一些记录,但是我知道最大的单元格样式 XSSFWorkbook
是64000。
但是记录超过64000,并认为我想cellstyle对每个单元格应用新的 样式, 否则 我将克隆已经存在的单元格样式。

即使是克隆,我也需要采用默认的单元格样式,
workbook.createCellStyle();
但这超出了64001条记录的限制,从而导致java.lang.IllegalStateException: The maximum number of cell styles was exceeded.

因此,POI中是否有任何信息可以知道已经存在特定的单元样式,并利用该样式或何时需要克隆/创建默认单元样式并进行克隆。

克隆的原因是:有时列/行cellstyle现有引用的excel 单元格样式可能有所不同,所以我采用默认的单元格样式并将克隆col&row和单元
格克隆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();
 }
}


 类似资料:
  • 我想在excel中写入一些记录,但我了解到中的最大单元格样式是64000。但超过64000的记录应考虑我要对每个单元格应用新的或我将使用已有的单元格样式进行克隆。 即使是克隆,我也需要使用默认单元格样式,但这超过了64001记录,从而导致。 因此,在POI中是否存在知道特定的单元格样式已经存在并利用它,或者何时需要克隆/创建默认的单元格样式和克隆。 克隆的原因是:有时column/row和现有引用

  • 在模板中使用自定义管道时,如下所示: 而且效果很好。 但它表明 用户名未定义

  • 问题内容: 是否可以 不 尝试加载就知道是否已加载Java类?尝试加载该类,但我不希望出现这种副作用。还有另一种方法吗? (我不想覆盖类加载器。我正在寻找一个相对简单的方法。) 问题答案: (感谢Aleksi)此代码: 产生: 请注意,示例类不在软件包中。完整的二进制名称是必需的。 二进制名称的一个示例是

  • 我从对象和对象数组中更改了一个对象两次,这样在第一次迭代中,我过滤掉了几个对象,在第二次迭代中,我使用map更改了每个过滤后的对象。我能用减速机或更好的吗?

  • 最近,我遇到了一个问题:我需要用java导出一个excel(xlsx),它必须包含这种单元格样式: 我用这个垂直文本制作了一个excel文件,并导出为xml文件。然后我发现该样式有一个名为“VerticalText”的属性: 根据经验,我选择了ApachePOI。但是我找不到任何方法用POI生成单元格样式。我只能找到旋转法,不能满足要求。 所以我读了更多的POI代码,发现cell样式是从一些xsb

  • 问题内容: 假设我有以下内容: 到回调被调用时,将不可避免地成为所有回调的最后一个变量,而不是像我希望的那样为每个回调都不同。我意识到我可以传递给回调函数,然后将其传递回去,但它是外部库的一部分,因此我不想弄乱它的源代码。 你们中那些比我更了解JavaScript的人,是否还有其他方法可以做我想做的事情? 谢谢, 问题答案: 处理这种情况的一种常见方法(如果很难看)是使用另一个函数,该函数立即被调