问题描述:

当多个word文档进行合并的时候,每个文档都有书签的话,会出现书签丢失的问题?

原因:

通过对word转换成xml进行分析,发现多个文档中的 w:bookmarkStart <w:bookmarkStart w:id="0" w:name="bm__1613808247536"/><w:r><w:rPr><w:rFonts w:hint="eastAsia"/><w:b/><w:color w:val="FF0000"/></w:rPr><w:t>log文件</w:t></w:r><w:bookmarkEnd w:id="0"/> 书签标记中的 w:id的值 会出现重复。

解决思路:

找出每个文档中的书签,然后为每个书签标记w:id 设置唯一值即可解决。

实现代码:

package com.htdd.dmp.common.utils;import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.htdd.common.utils.StringUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;import java.io.*;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;public class WordUtils {private static final Pattern pattern1 = Pattern.compile("<w:bookmarkStart w:id=\"\\d+\" w:name=\"\\w+\"/>");private static final Pattern pattern2 = Pattern.compile("w:id=\"\\d+\"");private static final int BOOKMARK_NUM = 100;// 每个word文档书签不能超过100public static void main(String[] args) throws Exception {List<String> list = Lists.newLinkedList();list.add("E:\\ts\\tt\\17.docx");list.add("E:\\ts\\tt\\18.docx");list.add("E:\\ts\\tt\\19.docx");list.add("E:\\ts\\tt\\20.docx");list.add("E:\\ts\\tt\\21.docx");list.add("E:\\ts\\tt\\22.docx");list.add("E:\\ts\\tt\\23.docx");String p = "E:\\ts\\tt\\ts.docx";merge(list,p);}public static void merge(List<String> filePaths, String destPath) {if(filePaths==null||filePaths.isEmpty()|| StringUtils.isEmpty(destPath)) {System.out.println(">>>>>>filePaths和destPath都不能为空!!!");return;}StringBuilder sb = new StringBuilder();XmlOptions optionOuter = new XmlOptions();optionOuter.setSaveOuter();AtomicInteger ai = new AtomicInteger(100);try(InputStream is = new FileInputStream(filePaths.get(0));XWPFDocument xwpf = new XWPFDocument(is)) {CTBody firstBody = xwpf.getDocument().getBody();Map<String,String> map = getContentMap(firstBody);String header = map.get("head");sb.append(header);String docStr = map.get("body");sb.append(dealBookMark(docStr,ai));String tail = map.get("tail");CTBody body;for (int i = 1; i < filePaths.size(); i++) {String path = filePaths.get(i);try(InputStream is2 = new FileInputStream(path);XWPFDocument xwpf2 = new XWPFDocument(is2)) {body = xwpf2.getDocument().getBody();docStr = getBody(body,optionOuter);ai.addAndGet(BOOKMARK_NUM*i);sb.append(dealBookMark(docStr,ai));}}try (OutputStream dest = new FileOutputStream(destPath)) {CTBody makeBody = CTBody.Factory.parse(sb.append(tail).toString());firstBody.set(makeBody);xwpf.write(dest);}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException | XmlException e) {e.printStackTrace();}}private static String getBody(CTBody src, XmlOptions optionsOuter) {String appendString = src.xmlText(optionsOuter);return appendString.substring(appendString.indexOf(">") + 1, appendString.lastIndexOf("<"));}private static Map<String, String> getContentMap(CTBody body){String srcString = body.xmlText();Map<String, String> map = Maps.newHashMap();String head = srcString.substring(0, srcString.indexOf(">") + 1);map.put("head", head);String mainPart = srcString.substring(srcString.indexOf(">") + 1, srcString.lastIndexOf("<"));map.put("body",mainPart);String tail = srcString.substring(srcString.lastIndexOf("<"));map.put("tail",tail);return map;}private static String dealBookMark(String docStr, AtomicInteger ai) {Matcher matcher = pattern1.matcher(docStr);Matcher m;while (matcher.find()) {String matchStr = matcher.group();m = pattern2.matcher(matchStr);if (m.find()) {String idStr = m.group();String idReplaceStr = "w:id=\"" + ai.getAndAdd(1) + "\"";docStr = docStr.replaceFirst(idStr,idReplaceStr).replaceFirst(idStr,idReplaceStr);}}return docStr;}
}

word文档合并,书签丢失相关推荐

  1. npoi操作word书签_100份Word文档合并只需3分钟?不用复制粘贴,简单到一学就会...

    办公中,我们时常会需要将很多份Word文档合并在一起,如果不会便捷的技巧光靠复制粘贴,那将会花费我们很多的时间和精力.所以,今天我们就是要教大家一个非常简单的方法,只用三分钟就能将上百份文档合并在一起 ...

  2. word文档合并的几种方式

    Word文档合并几种方式 通过com.spire.doc包 具体参考地址:https://www.e-iceblue.cn/spiredocforjavaoperating/merge-word-do ...

  3. java word 文档合并_Java 合并Word文档

    概述 合并文档可以是将两个包含一定逻辑关系的文档合并成一个完整的文档,也可以是出于方便文档存储.管理的目的合并多个文档为一个文档.下面,就将以上文档操作需求,通过Java程序来实现Word文档合并.合 ...

  4. 如何让多个word文档合并成一个

    几千年没发过动态了,今天随便发发证明本人健在吧! 近两天有几个同学问我Word文档合并成一个,我属实有些懵. 首先建立一个空白文档,在[插入]里面找到[对象],然后选择[从文件中提取],之后按照顺序选 ...

  5. Aspose.Words在word文档合并时如何控制列表编号

    为了帮助大家在进行word文档合并时灵活地控制列表编号,Aspose.Words for .NET为大家提供了ImportFormatMode属性设置来进行相应的操作.在本文中,我们会给出两个合并前的 ...

  6. word文档合并单元格在什么地方

    word文档合并单元格在哪里 演示机型:华为matebook X系统版本:win10APP版本:word2016 1.打开所要编辑的表格,选中所想要合并的单元格. 2.选中单元格后,单击布局功能区,在 ...

  7. C# 实现将多个word文档合并成一个word文档的功能

    https://www.cnblogs.com/zhenzaizai/p/7782748.html 前段时间项目上遇到这么一个需求,需要将多个OCR识别的word文档合并成一个,于是就在网上找了找,自 ...

  8. python实现word文档合并

    目录 背景: 设计思路: 查看各目录未提交名单: 合并word文件: 脚本环境说明: 完整代码: 功能执行效果图: 总结: 背景: 由于工作需要,现在有这么一个需求,要合并大量的word文档,而且要在 ...

  9. 利用Python实现word文档合并

    实现步骤: 1.安装依赖 pip install docx pip install docxcompose pip install pyinstaller // 将py文件打包成exe文件的库 2.编 ...

最新文章

  1. java避免使用orderby_java – Spring安全配置@Order不是唯一的例外
  2. python【力扣LeetCode算法题库】100-相同的树
  3. Sharepoint Caml查询中时间格式
  4. Linux 下编译并运行C语言程序
  5. web 日志分析工具 awstats 简单安装
  6. 文档类型定义和合法性(2)
  7. [BZOJ2655] calc
  8. nacos1.2(1.3)的下载及CentOS7下安装nacos
  9. iOS-字符串的连接
  10. mac 连接百度云服务器地址,教你怎么在 Mac 下把百度网盘映射到另一个文件夹
  11. sql 过滤空值_SQL 编程思想:一切皆关系!
  12. ubuntu下配置eclipse
  13. Shell脚本(函数,shell中的数组)
  14. js中~~和^=分别代表什么,用处是什么?
  15. 传智播客视频python视频爬虫
  16. 99乘法表c语言显示坐标,C语言打印九九乘法表
  17. 玩转飞思卡尔在线调试工具FreeMaster
  18. 网易云计算机系统有限公司,网易云音乐
  19. 2022年南航计算机考研统考录取情况统计
  20. itextPdf pdf加水印

热门文章

  1. 【安全】椭圆曲线加密算法(ECC)深入理解
  2. ADI公司高速PCB布板指南
  3. 安装宝塔面板后原ssh连接失败问题及解决
  4. 无头浏览器和抓取-解决方案
  5. ArcBlock 创始人冒志鸿应邀在猎豹移动演讲
  6. 快递管理系统 v2.0
  7. win10计算机亮度在哪里调,win10电脑怎么调亮度
  8. 3DSMAX中英文对照大全(从A-Z分类)
  9. Bingo说说:如何选对赚钱项目?3招教你不再迷茫
  10. 串扰(crosstalk)