maven依赖
< dependency> < groupId> io.github.java-diff-utils</ groupId> < artifactId> java-diff-utils</ artifactId> < version> 4.11</ version> </ dependency>
创建Diff 工具类
package com. system. utlis. diff ; import com. github. difflib. UnifiedDiffUtils ;
import com. github. difflib. patch. Patch ;
import org. springframework. stereotype. Component ; import java. io. * ;
import java. nio. charset. StandardCharsets ;
import java. nio. file. Files ;
import java. util. ArrayList ;
import java. util. HashMap ;
import java. util. List ;
import java. util. Map ;
import java. util. stream. Collectors ; @Component
public class DiffHandleUtils { public static void main ( String [ ] args) { List < String > diffString = DiffHandleUtils . diffString ( "E:\\test\\test1.java" , "E:\\test\\test2.txt" ) ; DiffHandleUtils . generateDiffHtml ( diffString, "E:\\test" ) ; System . out. println ( "diff完成" ) ; } public static List < String > diffString ( List < String > original, List < String > revised) { return diffString ( original, revised, null , null ) ; } public static List < String > diffString ( List < String > original, List < String > revised, String originalFileName, String revisedFileName) { originalFileName = originalFileName == null ? "原始文件" : originalFileName; revisedFileName = revisedFileName == null ? "对比文件" : revisedFileName; Patch < String > patch = com. github. difflib. DiffUtils. diff ( original, revised) ; List < String > unifiedDiff = UnifiedDiffUtils . generateUnifiedDiff ( originalFileName, revisedFileName, original, patch, 0 ) ; int diffCount = unifiedDiff. size ( ) ; if ( unifiedDiff. size ( ) == 0 ) { unifiedDiff. add ( "--- " + originalFileName) ; unifiedDiff. add ( "+++ " + revisedFileName) ; unifiedDiff. add ( "@@ -0,0 +0,0 @@" ) ; } else if ( unifiedDiff. size ( ) >= 3 && ! unifiedDiff. get ( 2 ) . contains ( "@@ -1," ) ) { unifiedDiff. set ( 1 , unifiedDiff. get ( 1 ) ) ; unifiedDiff. add ( 2 , "@@ -0,0 +0,0 @@" ) ; } List < String > original1 = original. stream ( ) . map ( v -> " " + v) . collect ( Collectors . toList ( ) ) ; return insertOrig ( original1, unifiedDiff) ; } public static List < String > diffString ( String filePathOriginal, String filePathRevised) { List < String > original = null ; List < String > revised = null ; File originalFile = new File ( filePathOriginal) ; File revisedFile = new File ( filePathRevised) ; try { original = Files . readAllLines ( originalFile. toPath ( ) ) ; revised = Files . readAllLines ( revisedFile. toPath ( ) ) ; } catch ( IOException e) { e. printStackTrace ( ) ; } return diffString ( original, revised, originalFile. getName ( ) , revisedFile. getName ( ) ) ; } public static void generateDiffHtml ( List < String > diffString, String htmlPath) { StringBuilder builder = new StringBuilder ( ) ; for ( String line : diffString) { builder. append ( escapeStr ( line) ) ; builder. append ( "\n" ) ; } String githubCss = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.1/styles/github.min.css" ; String diff2htmlCss = "https://cdn.jsdelivr.net/npm/diff2html/bundles/css/diff2html.min.css" ; String diff2htmlJs = "https://cdn.jsdelivr.net/npm/diff2html/bundles/js/diff2html-ui.min.js" ; String template = "<!DOCTYPE html>\n" + "<html lang=\"en-us\">\n" + " <head>\n" + " <meta charset=\"utf-8\" />\n" + " <link rel=\"stylesheet\" href=\"" + githubCss + "\" />\n" + " <link rel=\"stylesheet\" type=\"text/css\" href=\"" + diff2htmlCss + "\" />\n" + " <script type=\"text/javascript\" src=\"" + diff2htmlJs + "\"></script>\n" + " </head>\n" + " <script>\n" + " const diffString = `\n" + "temp\n" + "`;\n" + "\n" + "\n" + " document.addEventListener('DOMContentLoaded', function () {\n" + " var targetElement = document.getElementById('myDiffElement');\n" + " var configuration = {\n" + " drawFileList: true,\n" + " fileListToggle: true,\n" + " fileListStartVisible: true,\n" + " fileContentToggle: true,\n" + " matching: 'lines',\n" + " outputFormat: 'side-by-side',\n" + " synchronisedScroll: true,\n" + " highlight: true,\n" + " renderNothingWhenEmpty: true,\n" + " };\n" + " var diff2htmlUi = new Diff2HtmlUI(targetElement, diffString, configuration);\n" + " diff2htmlUi.draw();\n" + " diff2htmlUi.highlightCode();\n" + " });\n" + " </script>\n" + " <body>\n" + " <div id=\"myDiffElement\"></div>\n" + " </body>\n" + "</html>" ; template = template. replace ( "temp" , builder. toString ( ) ) ; File f = null ; File folder = new File ( htmlPath) ; if ( ! folder. exists ( ) && ! folder. isDirectory ( ) ) { folder. mkdirs ( ) ; } try { f = new File ( htmlPath + "diff.html" ) ; BufferedWriter buf = new BufferedWriter ( new OutputStreamWriter ( new FileOutputStream ( f) , StandardCharsets . UTF_8 ) ) ; buf. write ( template) ; buf. close ( ) ; } catch ( IOException e) { e. printStackTrace ( ) ; } } private static String escapeStr ( String linStr) { if ( linStr. contains ( "\\" ) ) { linStr = linStr. replaceAll ( "\\\\" , "\\\\\\\\" ) ; } if ( linStr. contains ( "</script>" ) ) { linStr = linStr. replaceAll ( "</script>" , "<\\\\/script>" ) ; } if ( linStr. contains ( "`" ) ) { linStr = linStr. replaceAll ( "`" , "\\\\`" ) ; } if ( linStr. contains ( "$" ) ) { linStr = linStr. replaceAll ( "\\$" , "\\\\\\$" ) ; } return linStr; } public static List < String > insertOrig ( List < String > original, List < String > unifiedDiff) { List < String > result = new ArrayList < > ( ) ; List < List < String > > diffList = new ArrayList < > ( ) ; List < String > d = new ArrayList < > ( ) ; for ( int i = 0 ; i < unifiedDiff. size ( ) ; i++ ) { String u = unifiedDiff. get ( i) ; if ( u. startsWith ( "@@" ) && ! "@@ -0,0 +0,0 @@" . equals ( u) && ! u. contains ( "@@ -1," ) ) { List < String > twoList = new ArrayList < > ( ) ; twoList. addAll ( d) ; diffList. add ( twoList) ; d. clear ( ) ; d. add ( u) ; continue ; } if ( i == unifiedDiff. size ( ) - 1 ) { d. add ( u) ; List < String > twoList = new ArrayList < > ( ) ; twoList. addAll ( d) ; diffList. add ( twoList) ; d. clear ( ) ; break ; } d. add ( u) ; } for ( int i = 0 ; i < diffList. size ( ) ; i++ ) { List < String > diff = diffList. get ( i) ; List < String > nexDiff = i == diffList. size ( ) - 1 ? null : diffList. get ( i + 1 ) ; String simb = i == 0 ? diff. get ( 2 ) : diff. get ( 0 ) ; String nexSimb = nexDiff == null ? null : nexDiff. get ( 0 ) ; insert ( result, diff) ; Map < String , Integer > map = getRowMap ( simb) ; if ( null != nexSimb) { Map < String , Integer > nexMap = getRowMap ( nexSimb) ; int start = 0 ; if ( map. get ( "orgRow" ) != 0 ) { start = map. get ( "orgRow" ) + map. get ( "orgDel" ) - 1 ; } int end = nexMap. get ( "revRow" ) - 2 ; insert ( result, getOrigList ( original, start, end) ) ; } int start = ( map. get ( "orgRow" ) + map. get ( "orgDel" ) - 1 ) ; start = start == - 1 ? 0 : start; if ( simb. contains ( "@@ -1," ) && null == nexSimb && map. get ( "orgDel" ) != original. size ( ) ) { insert ( result, getOrigList ( original, start, original. size ( ) - 1 ) ) ; } else if ( null == nexSimb && ( map. get ( "orgRow" ) + map. get ( "orgDel" ) - 1 ) < original. size ( ) ) { insert ( result, getOrigList ( original, start, original. size ( ) - 1 ) ) ; } } int diffCount = diffList. size ( ) - 1 ; if ( ! "@@ -0,0 +0,0 @@" . equals ( unifiedDiff. get ( 2 ) ) ) { diffCount = diffList. size ( ) > 1 ? diffList. size ( ) : 1 ; } result. set ( 1 , result. get ( 1 ) + " ( " + diffCount + " different )" ) ; return result; } public static void insert ( List < String > result, List < String > noChangeContent) { for ( String ins : noChangeContent) { result. add ( ins) ; } } public static Map < String , Integer > getRowMap ( String str) { Map < String , Integer > map = new HashMap < > ( ) ; if ( str. startsWith ( "@@" ) ) { String [ ] sp = str. split ( " " ) ; String org = sp[ 1 ] ; String [ ] orgSp = org. split ( "," ) ; map. put ( "orgRow" , Integer . valueOf ( orgSp[ 0 ] . substring ( 1 ) ) ) ; map. put ( "orgDel" , Integer . valueOf ( orgSp[ 1 ] ) ) ; String [ ] revSp = org. split ( "," ) ; map. put ( "revRow" , Integer . valueOf ( revSp[ 0 ] . substring ( 1 ) ) ) ; map. put ( "revAdd" , Integer . valueOf ( revSp[ 1 ] ) ) ; } return map; } public static List < String > getOrigList ( List < String > original1, int start, int end) { List < String > list = new ArrayList < > ( ) ; if ( original1. size ( ) >= 1 && start <= end && end < original1. size ( ) ) { for ( ; start <= end; start++ ) { list. add ( original1. get ( start) ) ; } } return list; }
}
测试效果