Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

java - Is there any way to know that the CellStyle is already present in Workbook(to reuse) using POI or to Copy only Celstyle obj not reference

I want to write some records into excel but I got to know that the maximum cell styles in XSSFWorkbook is 64000.But records exceeding more than 64000 and consider I want to apply new cellstyle to each cell or I will clone with the already existing cell style.

Even to clone I need to take default cell style workbook.createCellStyle(); but this exceeds for 64001 record which leads to java.lang.IllegalStateException: The maximum number of cell styles was exceeded..

So is there anyway in POI to know already particular cell style is present and make use of that or when is necessary to clone/create default cellstyle and clone.

Reason for cloning is : Sometimes column/row cellstyle and existing refered excel cellstyle may be different, so am taking default cell style and cloning col & row & cell cellstyles to it.

Even I tried to add a default style to a mapmap.put("defStyle",workbook.createCellStyle();) but this wont clone properly, because it will change at first attempt of cloning since It wont get the Object it will copy the reference even object cloning also not possible here because cellstyle doesn't implement cloneable interface.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In general it should not be necessary to create as much cell styles that they exceed the max count of possible cell styles. To format cells depending of their content, there is conditional formatting usable. Also to format rows (odd/even rows different for example) conditional formatting can be used. Also for columns.

So in general not each cell or a big amount of cells should be formatted using cell styles. Instead there should a less count of cell styles be created and then be used as default cell style or in single cases if conditional formatting really will not be possible.

In my example I have a default cell style for all cells and a single row cell style for first row (even this could be achieved using conditional formatting).

To keep the default cell style working after it is applied to all columns, it must be applied to all with apache poi new created cells. For this I have provided a method getPreferredCellStyle(Cell cell). Excel itself will apply the column (or row) cell style to new filled cells automatically.

If it is then nevertheless necessary to format single cells different, then for this CellUtil should be used. This provides "various methods that deal with style's allow you to create your CellStyles as you need them. When you apply a style change to a cell, the code will attempt to see if a style already exists that meets your needs. If not, then it will create a new style. This is to prevent creating too many styles. there is an upper limit in Excel on the number of styles that can be supported." See comments in my Example.

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();
 }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...