使用Apache POI获取新单元格的边框和填充样式

继发布@ POI Excel合并导致“修复的logging:从/xl/styles.xml部分(样式)格式”

我有两个excel文件,打开罚款风格和颜色(在Microsoft Office 2010中)。

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

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

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

导致样式问题“ Repaired Records:Format from /xl/styles.xml part(Styles)

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

有人可以提出围绕如何获得边框和填充单元格样式并应用于新单元格的想法?

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

根据关于该错误的评论5 ,可以通过手动复制填充和边界属性来解决这个问题。

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

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

https://issues.apache.org/bugzilla/show_bug.cgi?id=55800发表文章

由于我们在边界和填充方面遇到麻烦

下面添加一些像Charm一样工作的代码

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

你可以使用下面的代码。 我使用.xlsx进行了validation,我相信它也可以与.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); } }