• Java的POI-word模板生成目录自动更新


    目录问题:

    解决word模板目录在第一次打开不更新就不显示目录问题的原因:之前是通过动态替换域代码toc的形式,生成了一段域代码放置在Word的目录行,打开的时候无法直接触发渲染和更新。

    方案:通过插入-文档组件-域组件-目录和索引,将当前的模板的目录直接生成到文档的目录中,在数据替换的时候,由于目录用的也是正文的内容,所以直接就替换掉了。

    上述方案解决了需要手动更新才能显示,否则空白的问题。但是也存在缺点:只能更新目录的内容,目录的页码无法正确更新显示,是当时模板的页码。

    ------------------------------------------分界线-------------------------------------------------------------------------

    项目时间允许之际,又做了方案调研,用以下方案,完美解决:

    1、spire.doc

    有收费版本和免费版本,免费的版本只能读取500行的内容,并生成目录,所以不全,不用;

    收费版本的生成word后,会在文档第一行显示试用提示,将该行用poi删除即可;

    先用poi-tl的模板生成word,然后用spire.doc打开,并更新域,再保存到原文件路径即可,最后将第一行删掉:

    1. public class Demo4 {
    2. public static void main (String[] args) throws IOException {
    3. //加载已设置大纲级别的测试文档
    4. long start = System.currentTimeMillis();
    5. Document doc = new Document("D:\\project\\util\\src\\main\\resources\\poi\\report.docx");
    6. doc.updateTableOfContents();
    7. doc.saveToFile("目录2222311.docx", FileFormat.Docx_2010);
    8. restWord("目录2222311.docx");
    9. System.out.println((System.currentTimeMillis()-start)/1000);
    10. }
    11. private static void restWord(String docFilePath) {
    12. try (FileInputStream in = new FileInputStream(docFilePath)) {
    13. XWPFDocument doc = new XWPFDocument(OPCPackage.open(in));
    14. List paragraphs = doc.getParagraphs();
    15. if (paragraphs.size() < 1) return;
    16. XWPFParagraph firstParagraph = paragraphs.get(0);
    17. if (firstParagraph.getText().contains("Spire.Doc")) {
    18. doc.removeBodyElement(doc.getPosOfParagraph(firstParagraph));
    19. }
    20. OutputStream out = new FileOutputStream(docFilePath);
    21. doc.write(out);
    22. out.close();
    23. } catch (Exception e) {
    24. e.printStackTrace();
    25. }
    26. }
    27. }

    2、aspose.word

    aspose.word只有收费版本,如果公司允许,可以买了再用,没有预算的,可以找一个破解jar包引入即可,如果找不到,可以私信我:

    先用poi-tl的模板生成word,然后用aspose.word打开,并更新域,再保存到原文件路径即可:

    1. public class Demo5 {
    2. public static void main (String[] args) throws Exception {
    3. //加载已设置大纲级别的测试文档
    4. long start = System.currentTimeMillis();
    5. Document doc = new Document("D:\\project\\util\\src\\main\\resources\\poi\\report.docx");
    6. doc.updateFields();
    7. doc.save("33333.pdf", SaveFormat.PDF);//这里执行操作
    8. // restWord("目录33331221.docx");
    9. System.out.println((System.currentTimeMillis()-start)/1000);
    10. }
    11. private static void restWord(String docFilePath) {
    12. try (FileInputStream in = new FileInputStream(docFilePath)) {
    13. XWPFDocument doc = new XWPFDocument(OPCPackage.open(in));
    14. List paragraphs = doc.getParagraphs();
    15. if (paragraphs.size() < 1) {
    16. return;
    17. }
    18. XWPFParagraph firstParagraph = paragraphs.get(0);
    19. XWPFParagraph lastParagraph = paragraphs.get(paragraphs.size() - 1);
    20. if (firstParagraph.getText().contains("Aspose.Words")) {
    21. doc.removeBodyElement(doc.getPosOfParagraph(firstParagraph));
    22. doc.removeBodyElement(doc.getPosOfParagraph(lastParagraph));
    23. }
    24. OutputStream out = new FileOutputStream(docFilePath);
    25. doc.write(out);
    26. out.close();
    27. } catch (Exception e) {
    28. e.printStackTrace();
    29. }
    30. }

    总结,公司允许用破解版的,可以用aspose.word,效率高,生成PDF也给力;spire.doc是国内的产品,操作word耗时长,700+页的文档需要130s+的耗时,不能忍。

  • 相关阅读:
    小程序地图相关
    蓝桥杯入门即劝退(五)跑断腿的小蓝
    玩转Mysql系列 - 第19篇:游标详解
    可见光相机曝光方式
    【C++】list容器的基本操作
    程序员学习 CPU 有什么用?
    【jvm源码】-2.对象核心源码
    NOIP1998-2018年普及组 CSP-J2 2019 2020 解题报告及视频
    手撕C++入门基础
    Java后端开发&微服务面试题,有爱分享,祝顺利秋招
  • 原文地址:https://blog.csdn.net/qq_18846873/article/details/126823834