发布@ POI Excel Merging Causing "Repaired Records: Format from /xl/styles.xml part (Styles)"后的帖子
我有两个excel文件可以打开样式和颜色(在Microsoft Office 2010中)。
Iam使用上面线程中发布的代码合并这两个excel文件。
问题在于样式(我创建的样式如下):
newCellStyle = newCell.getSheet().getWorkbook().createCellStyle();
newCellStyle.cloneStyleFrom(oldCellStyle);
styleMap.put(stHashCode, newCellStyle);
导致样式问题“修复记录:来自/xl/styles.xml部分的格式(样式)”
经过大量研究后,我学到的是边界和填充是导致问题的原因。取消设置这些参数已解决了这个问题。但是因为它说边境和填补失踪了。有人可以提出如何从单元格获取边框和填充样式并应用于新单元格的想法吗?
答案 0 :(得分: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 :(得分:1)
在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);
}
答案 2 :(得分: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);
}
}