2017-09-26 54 views
1

我目前使用Apache POI库来生成Java中的excel文件。XSSF Excel命名样式

下面是我想知道的:在Excel中,可以创建将添加到工作簿的新单元格样式。这些样式可重复使用,可以从样式表中选择。

使用Apache POI,您可以在构建工作簿时做类似的事情。您可以创建一个附加到工作簿的新XSSFCellstyle,并且可以将其应用于任意多个单元格。但是,这些样式不可重用。如果我在Excel中打开生成的工作簿,并更改其中一种单元格样式,我将永远无法将其更改回到我在XSSF中生成的未命名样式。这些样式不会添加到工作簿的样式表中。

我只是想知道,有没有在Apache POI工作簿创建命名风格的任何手段,该文件在Excel中打开后,然后可以看到和resused?

编辑:在进一步的调查似乎有一种方法可以做到这一点使用HSSF,我们可以使用:

cellStyle.setUserStyleName("Header") 

我找不到一个相当于XSSF任何信息,但。任何人都知道是否有可能?

回答

2

如果使用Office OpenXML文件格式*.xlsx,这并不容易。但以下对我有用。

apache poi FAQ-N10025中所述,需要所有模式ooxml-schemas-1.3.jar的满罐。

import java.io.FileOutputStream; 
import java.io.FileInputStream; 

import org.apache.poi.xssf.usermodel.*; 
import org.apache.poi.ss.usermodel.*; 
import org.apache.poi.xssf.model.StylesTable; 

import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXf; 
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTStylesheet; 
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellStyles; 
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellStyle; 
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellStyleXfs; 

import java.lang.reflect.Field; 

public class CreateExcelNamedXSSFCellStyle { 

static void setNamedCellStyle(XSSFCellStyle style, String name) throws Exception { 

    Field _stylesSource = XSSFCellStyle.class.getDeclaredField("_stylesSource"); 
    _stylesSource.setAccessible(true); 
    StylesTable stylestable = (StylesTable)_stylesSource.get(style); 
    CTStylesheet ctstylesheet = stylestable.getCTStylesheet(); 

    CTCellStyles ctcellstyles = ctstylesheet.getCellStyles(); 

    CTXf ctxfcore = style.getCoreXf(); 

    if (ctcellstyles == null) { 
    ctcellstyles = ctstylesheet.addNewCellStyles(); 
    ctcellstyles.setCount(2); 

    CTCellStyle ctcellstyle = ctcellstyles.addNewCellStyle(); //CellStyle for default built-in cell style 
    ctcellstyle.setXfId(0); 
    ctcellstyle.setBuiltinId(0); 

    ctcellstyle = ctcellstyles.addNewCellStyle(); 
    ctcellstyle.setXfId(1); 
    ctcellstyle.setName(name); 

    ctxfcore.setXfId(1); 
    } else { 
    long stylescount = ctcellstyles.getCount(); 
    ctcellstyles.setCount(stylescount+1); 

    CTCellStyle ctcellstyle = ctcellstyles.addNewCellStyle(); 
    ctcellstyle.setXfId(stylescount); 
    ctcellstyle.setName(name); 

    ctxfcore.setXfId(stylescount); 
    } 

    CTXf ctxfstyle = CTXf.Factory.newInstance(); 
    ctxfstyle.setNumFmtId(ctxfcore.getNumFmtId()); 
    ctxfstyle.setFontId(ctxfcore.getFontId()); 
    ctxfstyle.setFillId(ctxfcore.getFillId()); 
    ctxfstyle.setBorderId(ctxfcore.getBorderId()); 

    stylestable.putCellStyleXf(ctxfstyle); 

} 

static XSSFCellStyle getNamedCellStyle(XSSFWorkbook workbook, String name) { 
    StylesTable stylestable = workbook.getStylesSource(); 
    CTStylesheet ctstylesheet = stylestable.getCTStylesheet(); 
    CTCellStyles ctcellstyles = ctstylesheet.getCellStyles(); 
    if (ctcellstyles != null) { 
    int i = 0; 
    XSSFCellStyle style = null; 
    while((style = stylestable.getStyleAt(i++)) != null) { 
    CTXf ctxfcore = style.getCoreXf(); 
    long xfid = ctxfcore.getXfId(); 
    for (CTCellStyle ctcellstyle : ctcellstyles.getCellStyleList()) { 
    if (ctcellstyle.getXfId() == xfid && name.equals(ctcellstyle.getName())) { 
     return style; 
    } 
    } 
    } 
    } 
    return workbook.getCellStyleAt(0); //if nothing found return default cell style 
} 

public static void main(String[] args) throws Exception { 

    XSSFWorkbook workbook = new XSSFWorkbook(); 
    //XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream("Mappe1.xlsx")); 

    XSSFCellStyle style = workbook.createCellStyle(); 
    style.setFillForegroundColor(new XSSFColor(new java.awt.Color(255, 0, 0))); 
    style.setFillPattern(FillPatternType.SOLID_FOREGROUND); 
    setNamedCellStyle(style, "My Custom Style 1"); 

    style = workbook.createCellStyle(); 
    style.setFillForegroundColor(new XSSFColor(new java.awt.Color(0, 255, 0))); 
    style.setFillPattern(FillPatternType.SOLID_FOREGROUND); 
    setNamedCellStyle(style, "My Custom Style 2"); 

    style = workbook.createCellStyle(); 
    style.setFillForegroundColor(new XSSFColor(new java.awt.Color(0, 0, 255))); 
    style.setFillPattern(FillPatternType.SOLID_FOREGROUND); 
    setNamedCellStyle(style, "My Custom Style 3"); 

    XSSFSheet sheet = workbook.createSheet("TestSheet"); 
    XSSFRow row = sheet.createRow(0); 
    for (int i = 0; i < 3; i++) { 
    XSSFCell cell = row.createCell(i); 
    style = getNamedCellStyle(workbook, "My Custom Style " + (i+1)); 
    cell.setCellStyle(style); 
    } 

    row = sheet.createRow(2); 
    XSSFCell cell = row.createCell(0); 
    style = getNamedCellStyle(workbook, "not found"); 
    cell.setCellStyle(style); 

    workbook.write(new FileOutputStream("CreateExcelNamedXSSFCellStyle.xlsx")); 
    workbook.close(); 

} 
} 
+0

谢谢!我一直试图用CTStyleSheet解决这个问题,但我错过了一些非常重要的步骤。再次感谢。 – DoonStar