2014-09-25 31 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); 
       } 
      }