Java的POI |
您所在的位置:网站首页 › 更新目录时按哪个键可以直接更新页码 › Java的POI |
目录问题: 解决word模板目录在第一次打开不更新就不显示目录问题的原因:之前是通过动态替换域代码toc的形式,生成了一段域代码放置在Word的目录行,打开的时候无法直接触发渲染和更新。 方案:通过插入-文档组件-域组件-目录和索引,将当前的模板的目录直接生成到文档的目录中,在数据替换的时候,由于目录用的也是正文的内容,所以直接就替换掉了。 上述方案解决了需要手动更新才能显示,否则空白的问题。但是也存在缺点:只能更新目录的内容,目录的页码无法正确更新显示,是当时模板的页码。 ------------------------------------------分界线------------------------------------------------------------------------- 项目时间允许之际,又做了方案调研,用以下方案,完美解决: 1、spire.doc 有收费版本和免费版本,免费的版本只能读取500行的内容,并生成目录,所以不全,不用; 收费版本的生成word后,会在文档第一行显示试用提示,将该行用poi删除即可; 先用poi-tl的模板生成word,然后用spire.doc打开,并更新域,再保存到原文件路径即可,最后将第一行删掉: public class Demo4 { public static void main (String[] args) throws IOException { //加载已设置大纲级别的测试文档 long start = System.currentTimeMillis(); Document doc = new Document("D:\\project\\util\\src\\main\\resources\\poi\\report.docx"); doc.updateTableOfContents(); doc.saveToFile("目录2222311.docx", FileFormat.Docx_2010); restWord("目录2222311.docx"); System.out.println((System.currentTimeMillis()-start)/1000); } private static void restWord(String docFilePath) { try (FileInputStream in = new FileInputStream(docFilePath)) { XWPFDocument doc = new XWPFDocument(OPCPackage.open(in)); List paragraphs = doc.getParagraphs(); if (paragraphs.size() < 1) return; XWPFParagraph firstParagraph = paragraphs.get(0); if (firstParagraph.getText().contains("Spire.Doc")) { doc.removeBodyElement(doc.getPosOfParagraph(firstParagraph)); } OutputStream out = new FileOutputStream(docFilePath); doc.write(out); out.close(); } catch (Exception e) { e.printStackTrace(); } } }2、aspose.word aspose.word只有收费版本,如果公司允许,可以买了再用,没有预算的,可以找一个破解jar包引入即可,如果找不到,可以私信我: 先用poi-tl的模板生成word,然后用aspose.word打开,并更新域,再保存到原文件路径即可: public class Demo5 { public static void main (String[] args) throws Exception { //加载已设置大纲级别的测试文档 long start = System.currentTimeMillis(); Document doc = new Document("D:\\project\\util\\src\\main\\resources\\poi\\report.docx"); doc.updateFields(); doc.save("33333.pdf", SaveFormat.PDF);//这里执行操作 // restWord("目录33331221.docx"); System.out.println((System.currentTimeMillis()-start)/1000); } private static void restWord(String docFilePath) { try (FileInputStream in = new FileInputStream(docFilePath)) { XWPFDocument doc = new XWPFDocument(OPCPackage.open(in)); List paragraphs = doc.getParagraphs(); if (paragraphs.size() < 1) { return; } XWPFParagraph firstParagraph = paragraphs.get(0); XWPFParagraph lastParagraph = paragraphs.get(paragraphs.size() - 1); if (firstParagraph.getText().contains("Aspose.Words")) { doc.removeBodyElement(doc.getPosOfParagraph(firstParagraph)); doc.removeBodyElement(doc.getPosOfParagraph(lastParagraph)); } OutputStream out = new FileOutputStream(docFilePath); doc.write(out); out.close(); } catch (Exception e) { e.printStackTrace(); } }总结,公司允许用破解版的,可以用aspose.word,效率高,生成PDF也给力;spire.doc是国内的产品,操作word耗时长,700+页的文档需要130s+的耗时,不能忍。 -------------------------------------------分界线---------------------------------------------------------------------- 以上方案已经解决了目录精确问题,在大文件word生成的时候,还存在2个问题: 1、并发调用会导致线程卡住,卡在new Document() 2、大文件更新目录的时候特别慢,也会出现卡死现象 解决方案: 1、添加synchronized同步锁,每次只有一个生成; 2、判断文件大小超过nMB时,不调用精确方法,小于的时候才调用,避免不可用问题 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |