poi操作ppt,XSLFTableCell.setText报错:java.lang.IndexOutOfBoundsException: Index: 1, Size: 1

时间:2022-06-29 17:33:01

POI版本3.14

用下面的代码生成一个带表格的pptx文件:

    public static void makeTablePpt() throws Exception{
//创建ppt
XMLSlideShow ppt = new XMLSlideShow();
//创建ppt页
XSLFSlide slide = ppt.createSlide();
//添加一个2行2列表格
XSLFTable table = slide.createTable(2, 2);
//获取第一行
XSLFTableRow row = table.getRows().get(0);
//获取第一行第一列
XSLFTableCell cell = row.getCells().get(0);
//格子赋值
cell.setText("a");
cell.setText("b");
OutputStream os = new FileOutputStream("e:/table.pptx");
ppt.write(os);
os.close();
}

发现报错:java.lang.IndexOutOfBoundsException: Index: 1, Size: 1。

如果XSLFTableCell只执行一次setText是不会报错的。

查看出错的源码:

    public XSLFTextRun setText(String text) {
if(!this._paragraphs.isEmpty()) {
CTTextBody txBody = this.getTextBody(false);
int cntPs = txBody.sizeOfPArray();

for(int i = cntPs; i > 1; --i) {
txBody.removeP(i - 1);
this._paragraphs.remove(i - 1);
}

((XSLFTextParagraph)this._paragraphs.get(0)).clearButKeepProperties();
}

return this.appendText(text, false);
}
是在操作_paragraphs属性的时候出错的,感觉应该是poi的bug。XSLFTableCell继承自XSLFTextShape,有属性:

private final List<XSLFTextParagraph> _paragraphs = new ArrayList();
存放文本段落。

XSLFTextParagraph有属性

private final List<XSLFTextRun> _runs;
存放文本。

可以直接操作XSLFTextRun来改变格子的值。

解决方法:

封装一个方法来改变表格的值:

    private static void setCellValue(XSLFTableCell c, String txt) {
XSLFTextParagraph tp = c.getTextParagraphs().isEmpty() ?
c.addNewTextParagraph() : c.getTextParagraphs().get(0);
XSLFTextRun run = tp.getTextRuns().isEmpty() ?
tp.addNewTextRun() : tp.getTextRuns().get(0);
run.setText(txt);
}

于是上面的代码改为:

    public static void makeTablePpt() throws Exception{
//创建ppt
XMLSlideShow ppt = new XMLSlideShow();
//创建ppt页
XSLFSlide slide = ppt.createSlide();
//添加一个2行2列表格
XSLFTable table = slide.createTable(2, 2);
//获取第一行
XSLFTableRow row = table.getRows().get(0);
//获取第一行第一列
XSLFTableCell cell = row.getCells().get(0);
//格子赋值
setCellValue(cell, "a");
setCellValue(cell, "b");
OutputStream os = new FileOutputStream("e:/table.pptx");
ppt.write(os);
os.close();
}