POI 读取word模板,动态添加图表,添加表格,段落(全)

第一个坑:读取docx的方式。

XWPFDocument document = null;
document = new XWPFDocument(POIXMLDocument.openPackage(mdlepath));

 这种方法读取docx文档,修改后另存为另一个文档

FileOutputStream outputStream = new FileOutputStream(tempPath);
document.write(outputStream);
outputStream.close();

 

 然后这个文档就可以使用勒。是不是很简单,是不是很方便。但是,这个代码我是在网上找的,这个代码有个巨坑无比的地方。

我在操作一个word的时候,调用了一个copyTable方法。这个方法的作用就是复制某一个表格到指定位置。中间使用了一个document.setTable(pos,table)方法。这个方法有个巨坑的点,其中table是我需要复制的表格。再执行完这个代码之后,doc.getTable()这个函数的返回值正确,没有问题,逐行遍历表格也没有问题。但是在操作这个表格的时候发现了问题。使用逐行操作表格会无效。究其原因我猜测是因为引用问题。POI在操作table的时候并不能像List一样。new 一个对象就新分配一个空间。POI在操作很多东西的时候并不能新分配一个对象,而没有引用。所以就导致我的setTable方法传入参数的table,永远是同一个table。我是怎么知道的呢,是因为我每次把这个table的某一个单元格setText("i="+i)会发现复制的几个表格里,最后一个表格输出了很多个i=.......在逐个遍历表格赋值的时候,会造成每次修改的表格都是同一个。并不能修改到复制出来的表格。解决办法就是必须把这个文件另存为,再打开。这是背景。

那么我就需要调用两次上面的代码。而且第二次调用的docx文件是第一次的输出文件。

这个东西我是要挂载在服务器上的,我肯定是要删除掉的。那么坑就来了。

我第一次生成的文件叫temp1,第二次生成的文件叫temp2.

我执行这一段代码:

out1.getFD().valid();
out2.getFD().valid();

输出结果为false和false。然后我删除文件。输出删除结果,均为true。然后我打开文件夹,发现temp

,删除了temp2没删除。我心态崩掉了。然后我file(temp1).exists();发现结果为false。就是说我删除成功而且检查删除后文件已经不存在了。然后我debug,发现删除那句话并没有执行,却返回true。没删除掉exists却返回false。然后我怀疑是文件占用或者是别的原因,我就怀疑是这个封装方法出了问题。

解决办法:

try (FileInputStream argIS = new FileInputStream(mdlepath);XWPFDocument document = new XWPFDocument(argIS)){
//这里面的代码就是操作整个document的具体操作了。
//不需要关闭 FileInputStream 会自动关闭
}

 我换了一种方法读取docx文件,而且写在try()中间.就不会出现占用或者流未关闭的问题了。

解决办法是看的官方例程http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/xwpf/usermodel/examples/

 

第二个坑:setTable()需要重新打开后生效

 

public static void copyTable(XWPFDocument doc, Integer mdlIndex, Integer startPos, Integer copysiz, List<String> titlelist,XWPFParagraph sourse) throws Exception {

        if (mdlIndex == null || mdlIndex >= doc.getTables().size() || mdlIndex < 0) {
            return;
        }
        XWPFTable table = doc.getTables().get(mdlIndex);


        // Copying a existing table
        CTTbl ctTbl = CTTbl.Factory.newInstance(); // Create a new CTTbl for the new table
        ctTbl.set(table.getCTTbl()); // Copy the template table's CTTbl
         // Create a new table using the CTTbl upon.0
        XWPFTable table2 = new XWPFTable(ctTbl, doc);//这个table2是个引用类型,放到循环里也不会改变他引用的对象是他的模板table,这是个坑;


        for (int i = 0; i < copysiz; i++) {

            //创建表之前先创建头
            XWPFParagraph paragraph = doc.createParagraph();
            paragraph.getCTP().setPPr(sourse.getCTP().getPPr());
//            paragraph.setPageBreak(true);
//            paragraph.setAlignment(ParagraphAlignment.CENTER);
            XWPFRun xwpfRun = paragraph.createRun();
            xwpfRun.setFontSize(18);//设置字体大小
            xwpfRun.setBold(true);
            xwpfRun.setText("表-" + titlelist.get(i+1));
            paragraph.setPageBreak(true);//分页符

            //创建表并且修改表
            doc.createTable(); // Create a empty table in the document

            // 这里有一个坑,必须重新打开该文件这个这个替换掉的table才能修改。不然改不了。或者在创建table2的时候就把数据加上
            doc.setTable(doc.getTables().size() - 1, table2);
        }

    }

 第三个坑:操作POIword图表

首先有例程

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值