# 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. 演示效果撒
