# java_diff_html **Repository Path**: zuijsy/java_diff_html ## Basic Information - **Project Name**: java_diff_html - **Description**: https://blog.csdn.net/qq_32448877/article/details/123129487 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2022-02-25 - **Last Updated**: 2025-03-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # java 最长公共字符算法实现文档内容字符串对比并返回差异html ## 1. 读取docx文档 > 使用POI进行文档的读取 ~~~java /** * 获取文档内容 * @param path 文档磁盘路径 * @throws IOException */ private StringBuilder getDocText(String path ) throws IOException { StringBuilder builder= new StringBuilder(); XWPFDocument doc = new XWPFDocument(new FileInputStream(path)); List elements = doc.getBodyElements(); for (IBodyElement element : elements) { // 段落 if (element instanceof XWPFParagraph) { XWPFParagraph paragraph = (XWPFParagraph) element; List runs = paragraph.getRuns(); //空行用标签换行 if (runs.size() == 0) { builder.append("
"); } for (XWPFRun run : runs) { builder.append(run.text()); } }// 表格 else if (element instanceof XWPFTable) { XWPFTable table= (XWPFTable) element; // 获取每个单元格 List rows = table.getRows(); for (XWPFTableRow row : rows) { List cells = row.getTableCells(); for (XWPFTableCell cell : cells) { // 一个单元格可以理解为一个word文档,单元格里也可以加段落与表格 List paragraphs = cell.getParagraphs(); for (XWPFParagraph paragraph : paragraphs) { List runs = paragraph.getRuns(); //空单元格用空格代替 if (runs.size() == 0) { builder.append(" "); } for (XWPFRun run : runs) { builder.append(run.text()+" "); } } } //每行加个换行标签 builder.append("
"); } } } return builder; } ~~~ ## 2. 查找最长公共子串 该方法引用自:[Java算法——求出两个字符串的最长公共字符串 - 春秋阕 - 博客园 (cnblogs.com)](https://www.cnblogs.com/Springtie/p/4068964.html) ~~~java /** * 查找最长公共字符算法 * @param str1 * @param str2 * @return */ private StringBuilder maxUtil2(String str1, String str2) { //把字符串转成字符数组 char[] arr1 = str1.toCharArray(); char[] arr2 = str2.toCharArray(); // 把两个字符串分别以行和列组成一个二维矩阵 int[][] temp = new int[arr1.length][arr2.length]; // 存储最长公共子串长度 int length = 0; //start表明最长公共子串的起始点,end表明最长公共子串的终止点 int end = 0; int start = 0; ////初始化二维矩阵中的第一行 for (int i = 0; i < arr2.length; i++) { temp[0][i] = (arr1[0] == arr2[i]) ? 1 : 0; } //初始化二维矩阵中的第一列 for (int j = 0; j < arr1.length; j++) { temp[j][0] = (arr2[0] == arr1[j]) ? 1 : 0; } //嵌套for循环:比较二维矩阵中每个点对应行列字符中否相等,相等的话值设置为1,否则设置为0 for (int i = 1; i < arr1.length; i++) { for (int j = 1; j < arr2.length; j++) { if (arr1[i] == arr2[j]) { temp[i][j] = temp[i - 1][j - 1] + 1; if (temp[i][j] > length) { length = temp[i][j]; end = j; } } else temp[i][j] = 0; } } //求出最长公共子串的起始点 start=end-length+1; StringBuilder sb=new StringBuilder(); //通过查找出值为1的最长对角线就能找到最长公共子串 for (int j = start; j < end+1; j++) { sb.append(arr2[j]); } return sb; } ~~~ ## 3. 代码实现 ~~~java @Data @AllArgsConstructor public class DiffObject { /** * 公共子串 */ private String name; /** * 起始位置 */ private Integer index; } ~~~ 调用方法代码实现 ~~~java public static void main(String[] args) { //返回新旧文本的html的map对象 HashMap map = new HashMap(); //获取文件保存路径 String oldUrl="C:/Users/12855/Desktop/1.docx"; String newUrl="C:/Users/12855/Desktop/2.docx"; //原始文件内容 StringBuilder oldText = null; //最新文件内容 StringBuilder newText = null; try { //获取文档内容 oldText= getDocText(oldUrl); newText= getDocText(newUrl); } catch (IOException e) { e.printStackTrace(); } // 随机生成字符串 String strOne = oldText.toString(); String strTwo = newText.toString(); //遍历查询到的文档名字 ArrayList demotes = new ArrayList(); while (true) { //获取最长公共子串 String same = maxUtil2(strOne, strTwo).toString(); if (same.length() <= 0) { break; } demotes.add(new DiffObject(same,strTwo.indexOf(same))); strOne= strOne.replace(same,"-"); strTwo= strTwo.replace(same,"*"); } String div=""+newText.toString()+""; for (DiffObject demote : demotes) { div= div.replace(demote.getName(),""+demote.getName()+""); } map.put("oldHtml",oldText.toString()); map.put("newHtml",div); System.out.println(map.get("oldHtml")); System.out.println(map.get("newHtml")); } ~~~ ## 4. 测试文件 1.docx ~~~ 根据气象部门的预报,河北中部、四川盆地西部、贵州西部、湖北中部和东南部、湖南北部、江苏中部、江西中部等地部分地区有大雾。 而内蒙古东北部、黑龙江西北部、新疆南疆西部、西藏大部、青海南部等地部分地区有小到中雪或雨夹雪。下雪天气主要分布在西部高寒地区,还有就是零星分布在北方和东北地区,对于全国影响不大。而下雨地区也是在西南地区,如西藏东南部、四川盆地西部、贵州中西部、云南东部等地有小雨。 标题1 标题2 标题3 标题4 标题5 而内蒙 北 江西 南疆 藏大 星分 东北 全国影 雨 州中 有小 零星 东北 区 西中 ~~~ 2.docx ~~~ 根据气象部门的预报,河北中部、四川方和西部、贵州西部、湖北中部和东南部、湖南北部、江苏中部、江西中部等地部分地区有大雾。 而内蒙得到部、黑龙江西北部、新疆西部、西藏大部、青海间距地部分地方和小到中雪或雨夹雪。下雪天气主要分布间距高寒地区,还有就是零星分布行方和东北地区,对2更方和影响不大。而44下雨地区也是在西南地区,如东南部、四川5u盆地西部、贵州中西部、云南东方和地有小雨。 标题1 标题2 标题3 标题4 标题5 而内蒙 北 江西 南疆 藏大 星分 东中雪或北 对于全国 雨天 零星 而内蒙 零星 东北江西 藏大 西中 ~~~ index.html ~~~html
最新版本:
历史版本:
~~~ ## 5. 演示效果撒 ![image-20220225112726271](image-20220225112726271.png)