2014-09-25 24 views
2

填充样式之后做出@POI Excel Merging Causing "Repaired Records: Format from /xl/styles.xml part (Styles)"使用Apache POI获得边境及新细胞

后我有被打开与款式和颜色的罚款(在Microsoft Office 2010)两个Excel文件。

Iam使用上面线程中发布的代码合并这两个excel文件。

的问题是与样式(我创建的样式如下):

newCellStyle = newCell.getSheet().getWorkbook().createCellStyle(); 
     newCellStyle.cloneStyleFrom(oldCellStyle); 
     styleMap.put(stHashCode, newCellStyle); 

这已经引起了风格问题“修复记录:从格式部分/xl/styles.xml(样式)

经过相当数量的研究后,我了解到的是边界和填充导致的问题。不设置这些参数解决了这个问题。但是,因为它说明边界和填补失踪。

有人可以提出围绕如何获取边框和填充细胞样式并应用于新细胞的想法?

回答

1

继后在https://issues.apache.org/bugzilla/show_bug.cgi?id=55800

我们正与边境麻烦,并填写

添加下面的代码工作就像魅力

newCellStyle = newCell.getSheet().getWorkbook().createCellStyle(); 
      newCellStyle.cloneStyleFrom(oldCellStyle); 
      //   newCellStyle.getCoreXf().unsetBorderId(); 
      //   newCellStyle.getCoreXf().unsetFillId(); 
      StylesTable newStylesSource = newCell.getSheet().getWorkbook().getStylesSource(); 
      StylesTable oldStylesSource = oldCell.getSheet().getWorkbook().getStylesSource(); 
      for (XSSFCellFill fill : oldStylesSource.getFills()) 
      { 
      XSSFCellFill fillNew = new XSSFCellFill(fill.getCTFill()); 
      newStylesSource.putFill(fillNew); 
      } 
      for (XSSFCellBorder border : oldStylesSource.getBorders()) 
      { 
      XSSFCellBorder borderNew = new XSSFCellBorder(border.getCTBorder()); 
      newStylesSource.putBorder(borderNew); 
      } 
2

这似乎是一个bug in Apache POI, #55800。 “CoreXf”对象中使用的边框ID和填充ID不会被复制,导致该问题。

根据Comment 5 on that bug,可以通过手动复制填充和边框属性来解决该问题。

原因是它不会复制XSSFCellFill和XSSFCellBorder。这也带来了边界问题。我在org.apache.poi.xssf.model.StylesTable中添加了一个方法,这将有助于创建工作簿的副本。

public void copyTo(StylesTable stylesTable){ 
    stylesTable.numberFormats.clear(); 
    stylesTable.fonts.clear(); 
    stylesTable.fills.clear(); 
    stylesTable.borders.clear(); 
    stylesTable.styleXfs.clear(); 
    stylesTable.xfs.clear(); 
    stylesTable.dxfs.clear(); 

    for(String str : numberFormats.values()) 
     stylesTable.putNumberFormat(str); 

    for(XSSFFont font : fonts){ 
     XSSFFont fontNew = new XSSFFont(font.getCTFont()); 
     fontNew.registerTo(stylesTable); 
    } 
    for(XSSFCellFill fill : fills){ 
     XSSFCellFill fillNew = new XSSFCellFill(fill.getCTFill()); 
     stylesTable.putFill(fillNew); 
    } 
    for(XSSFCellBorder border : borders){ 
     XSSFCellBorder borderNew = new XSSFCellBorder(border.getCTBorder()); 
     stylesTable.putBorder(borderNew); 
    } 
    for(CTXf ctxf : styleXfs){ 
     CTXf ctxfNew = (CTXf)ctxf.copy(); 
     stylesTable.putCellStyleXf(ctxfNew); 
    } 
    for(CTXf ctxf : xfs){ 
     CTXf ctxfNew = (CTXf)ctxf.copy(); 
     stylesTable.putCellXf(ctxfNew); 
    } 
    for(CTDxf dxf : dxfs){ 
     CTDxf dxfNew = (CTDxf)dxf.copy(); 
     stylesTable.putDxf(dxfNew); 
    } 
} 
1

你可以使用以下代码。我使用.xlsx进行了验证,我相信它也可以与.xls一起使用。

  int stHashCode = oldCell.getCellStyle().hashCode(); 
      CellStyle newCellStyle = newCell.getSheet().getWorkbook().createCellStyle(); 
      newCellStyle.cloneStyleFrom(oldCell.getCellStyle()); 
      newCell.setCellStyle(newCellStyle); 
      styleMap.put(stHashCode, newCellStyle); 

      if ((newCell.getSheet().getWorkbook() instanceof XSSFWorkbook) && (oldCell.getSheet().getWorkbook() instanceof XSSFWorkbook)){ 
       StylesTable newStylesSource = ((XSSFWorkbook) newCell.getSheet().getWorkbook()).getStylesSource(); 
       StylesTable oldStylesSource = ((XSSFWorkbook) oldCell.getSheet().getWorkbook()).getStylesSource(); 
       for (XSSFCellFill fill : oldStylesSource.getFills()) { 
        XSSFCellFill fillNew = new XSSFCellFill(fill.getCTFill()); 
        newStylesSource.putFill(fillNew); 
       } 
       for (XSSFCellBorder border : oldStylesSource.getBorders()) { 
        XSSFCellBorder borderNew = new XSSFCellBorder(border.getCTBorder()); 
        newStylesSource.putBorder(borderNew); 
       } 
      }