eec icon indicating copy to clipboard operation
eec copied to clipboard

通过Excel模板导出数据时发生Cannot invoke "java.awt.Color.getRGB()" because "color" is null

Open micro2600 opened this issue 8 months ago • 6 comments

Caused by: java.lang.NullPointerException: Cannot invoke "java.awt.Color.getRGB()" because "color" is null
  at org.ttzero.excel.entity.style.ColorIndex.indexOf(ColorIndex.java:54)
  at org.ttzero.excel.entity.style.Border.writeProperties(Border.java:561)
  at org.ttzero.excel.entity.style.Border.toDom(Border.java:478)
  at org.ttzero.excel.entity.style.Styles.writeTo(Styles.java:568)
  at org.ttzero.excel.entity.e7.XMLWorkbookWriter.writeGlobalAttribute(XMLWorkbookWriter.java:181)
  at org.ttzero.excel.entity.e7.XMLWorkbookWriter.createTemp(XMLWorkbookWriter.java:416)
  at org.ttzero.excel.entity.e7.XMLWorkbookWriter.writeTo(XMLWorkbookWriter.java:124)
  at org.ttzero.excel.entity.Workbook.writeTo(Workbook.java:712)

micro2600 avatar Jun 26 '25 01:06 micro2600

看上去像是没有拿到边框颜色,如果可以的话将模板发我一份

临时的你可以使用下面代码来避免NPE,使用自定义TemplateSheet并预判断边框颜色是否为NULL,如果为NULL则取消边框,可能会出现与预期样式不一致的情况

    public class MyTemplateSheet extends TemplateSheet {
       
        @Override
        protected int init() throws IOException {
            int r = super.init();
            
            // 使用反射拿到所有Border并判断颜色是否为NULL
            Styles styles = workbook.getStyles();
            for (Integer xf : styleMap.values()) {
                Border border = styles.getBorder(xf);
                Border.SubBorder[] borders = border.getBorders();
                for (int i = 0; i < borders.length; i++) {
                    // 颜色为NULL时替换取消边框
                    if (borders[i].color == null) {
                        borders[i] = new Border.SubBorder(BorderStyle.NONE, Color.WHITE);
                    }
                }
            }
            return r;
        }
    }

wangguanquan avatar Jun 26 '25 02:06 wangguanquan

马拉松男子前3名.xlsx 还有一个问题,如果单元格里出现单引号,如“Top 3 Man's Marathon”,输出为“Top 3 Man's Marathon”

micro2600 avatar Jun 26 '25 03:06 micro2600

上面的输出的点问题,应该是"Top 3 Man's Marathon"里的单号会转成“&aops”

micro2600 avatar Jun 26 '25 03:06 micro2600

上面的输出的点问题,应该是"Top 3 Man's Marathon"里的单号会转成“&aops”

原始文件里有就是Top 3 Man&apos ;s Marathon,读取的时候没有进行转义处理,目前读取的时候仅对'<','>','&',' ','"'这5个字符进行了转义处理,可以使用下面代码临时处理,完整代码如下,直接复制可用(不要使用上面回复的代码)

public class MyTemplateSheet extends TemplateSheet {

    public MyTemplateSheet(Path templatePath) {
        super(templatePath);
    }

    @Override
    protected int init() throws IOException {
        int r = super.init();

        // 获取所有Border并判断颜色是否为NULL
        Styles styles = workbook.getStyles();
        for (Integer xf : styleMap.values()) {
            Border border = styles.getBorder(styles.getStyleByIndex(xf));
            System.out.println(border);
            Border.SubBorder[] borders = border.getBorders();
            for (int i = 0; i < borders.length; i++) {
                Border.SubBorder subBorder = borders[i];
                // 颜色为NULL时替换黑色
                if (subBorder != null && subBorder.style != BorderStyle.NONE && subBorder.color == null) {
                    borders[i] = new Border.SubBorder(subBorder.style, Color.BLACK);
                }
            }
        }
        return r;
    }

    @Override
    protected void rowEnd(org.ttzero.excel.reader.Row row0, org.ttzero.excel.entity.Row row) {
        super.rowEnd(row0, row);

        for (Cell cell : row.cells) {
            if (cell.t == Cell.INLINESTR && cell.stringVal != null && cell.stringVal.contains("&apos;")) {
                cell.stringVal = cell.stringVal.replace("&apos;", "'"); // 特殊处理
            }
        }
    }
}

wangguanquan avatar Jun 26 '25 03:06 wangguanquan

问题已经解决。谢谢!

micro2600 avatar Jun 26 '25 04:06 micro2600

v0.5.25已修复该问题

wangguanquan avatar Oct 09 '25 10:10 wangguanquan