首页 文章

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

提问于
浏览
2

关注帖子@ POI Excel Merging Causing "Repaired Records: Format from /xl/styles.xml part (Styles)"

我有两个excel文件,它们在样式和颜色方面都很好(在Microsoft Office 2010中) .

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

问题在于样式(我创建的样式如下):

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

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

经过大量的研究,我学到的是边界和填充是导致问题的原因 . 取消设置这些参数已解决了这个问题 . 但由于它表示边界和填充失踪 .

有人可以围绕如何从单元格获取边框和填充样式并应用于新单元格吗?

3 回答

  • 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

    发表于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);
              }
    
  • 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);
                    }
                }
    

相关问题