java文本比较解决方案

参考资料

VBA计算页码和行号https://learn.microsoft.com/zh-cn/office/vba/api/word.wdinformation


概述:

最近在做word文档对比的,总结了几种解决方案,记录一下

在java中,常用的文本对比方案有如下几种:

|---------------|----------|----------|-----------|-----|
| 差异比较工具 | 小部分修改合理性 | 大片段修改合理性 | 修改部分定位便捷性 | 容错度 |
| java-diff | 差 | 差 | 差 | 差 |
| beyondCompare | 差 | 差 | 差 | 差 |
| WPS | 优 | 中 | 优 | 优 |
| git | 差 | 优 | 差 | 差 |

总结:

  • git/jgit 适用于整个段落的增删改,但是对段落内部的细节处理捕捉欠佳,如果一整段话仅仅修改了一个字,那么也会认为是段落的替换;
  • WPS的比较 适用于细节字符的增删改,但是对大片段落的增删改捕捉欠佳, 如果是一段话替换成了另一段话,那么不会被识别为段落的替换,而是找到里面的相似部分,表现为内部某些字符的增删改;
  • 建议两种插件结合着使用,可以使用字符串相似度等插件,来做到取长补短的效果;

具体介绍:

如果对比的word,可以使用VBA进行解析,见本人的VBA系列文章,这里就不做赘述。

1.java-diff

java-diff-utils 网上教程其实很多,这里是一个例子

2. beyondCompare

beyondCompare是一款PC版的文件对比工具,或许可以尝试用VBA来进行调用,参考文章:

3. WPS

WPS有word对比功能,在Word软件中的审阅→比较选项

可以使用VBA来使用此功能,参照文档,

下面是一段jacob代码

java 复制代码
package com.example.worddemo.test.jacob;

import com.example.worddemo.test.jacob.enums.FileMacroEnum;
import com.example.worddemo.utils.IdUtil;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;

/**
 * @program: word-demo
 * @description: 文档对比  最简单方式的文档对比方式
 * @author: wjl
 * @create: 2024-03-26 14:36
 **/
public class CompareDocuments {


    // 这里需要根据当前环境安装的是 MicroSoft Office还是WPS来选择
    // 如果安装的是WPS,则需要使用 KWPS.Application
    // 如果安装的是微软的 Office,需要使用 Word.Application
    private static final String MS_OFFICE_APPLICATION = "Word.Application";
    private static final String WPS_OFFICE_APPLICATION = "KWPS.Application";

    public static void main(String[] args) {
        ComThread.InitSTA();  // 初始化 COM 线程
        FileMacroEnum macroEnum = FileMacroEnum.WORD_2003_DOC;
        String targetPath = "D:\\"+ IdUtil.upper()+macroEnum.getSuffix();
        String sourceWordPath =  "D:\\3.doc";
        String targetWordPath =  "D:\\3 - 1.doc";
        try {
            ActiveXComponent app = new ActiveXComponent( WPS_OFFICE_APPLICATION);
            app.setProperty("Visible", new Variant(false));
            Dispatch docs = app.getProperty("Documents").toDispatch();
            Dispatch sourceDoc = Dispatch.invoke(docs, "Open", Dispatch.Method, new Object[] {sourceWordPath, new Variant(false), new Variant(true)} , new int[1]).toDispatch(); //打開word文檔
            Dispatch targetDoc = Dispatch.invoke(docs, "Open", Dispatch.Method, new Object[] {targetWordPath, new Variant(false), new Variant(true)} , new int[1]).toDispatch(); //打開word文檔

            // 然后进行比较  只填写必须的 其他的使用默认值
            Dispatch compareDoc = app.invoke("CompareDocuments", new Variant(sourceDoc), new Variant(targetDoc)).toDispatch();
            // 然后将 比较后的文档进行保存
            Dispatch.call(compareDoc, "SaveAs", targetPath, macroEnum.getMacro());
            Dispatch.call(compareDoc, "Close", false);
            Dispatch.call(sourceDoc, "Close", false);
            Dispatch.call(targetDoc, "Close", false);
            app.invoke("Quit",0);
        }catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            ComThread.Release();  // 释放 COM 线程
        }
        System.out.println("转换后的文件路径为:"+targetPath);
    }
}

4.git

java使用Git功能,可以使用Jgit插件,参照本人文档

5.总结

  • 如果两个文档只是细枝末节的差异,没有大段落的差异,使用WPS比较即可
  • 如果只有大段落的增删,建议使用Jgit
  • 如果两者都有,建议WPS和Jgit结合着使用
相关推荐
MandalaO_O11 分钟前
IDEA 开发(快捷键 + 调试 + 序列化)
java·ide·intellij-idea
xiaoqiMikko1 小时前
JVM 线上排查实战(七):jps 看不见它、jstack 连不上它,可它明明活得好好的
java·jvm
狼爷2 小时前
Rust/Go/Java/Python/PHP 大比拼:负载下后端框架到底差多少?
java·后端·编程语言
念何架构之路2 小时前
zap扩展生态与总结
java·前端·数据库
第七页独白3 小时前
汽车零件厂如何通过 QMS 真正落地 IATF 16949——QMS软件系统:品质检验-内审稽核-8d客诉管理:全星质量管理软件系统
java·前端·数据库
QCoding3 小时前
Spring AI Alibaba Graph实战:从ReAct Agent到Workflow,企业AI复杂流程该如何编排?
java·人工智能
用户094248568033 小时前
第25章:Java虚拟线程(Project Loom)实战与调度协作
java·jvm
砚底藏山河3 小时前
量化实战:截面因子有效性检验(IC 分析与分层回测)
java·python·金融·maven
wuminyu3 小时前
ForkJoinPool内部WorkQueue的Lock-Free数组操作以及并发任务窃取原理剖析
java·linux·c语言·jvm·c++
Elastic 中国社区官方博客3 小时前
使用 Lucene 搜索你的 Bean — 索引
java·大数据·数据库·elasticsearch·搜索引擎·全文检索·lucene