< dependency> < groupId> </ groupId> < artifactId> </ artifactId> < version> </ version> </ dependency> 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 > =  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 > ,  List < String > )  { 
    return  diffString ( original,  revised,  null ,  null ) ; 
  } 
  
  public  static  List < String > diffString ( List < String > ,  List < String > ,  String  originalFileName,  String  revisedFileName)  { 
    originalFileName =  originalFileName ==  null  ?  "原始文件"  :  originalFileName; 
    revisedFileName =  revisedFileName ==  null  ?  "对比文件"  :  revisedFileName; 
    
    Patch < String > =  com. github. difflib.  DiffUtils. diff ( original,  revised) ; 
    
    List < String > =  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 > =  original. stream ( ) . map ( v ->  " "  +  v) . collect ( Collectors . toList ( ) ) ; 
    
    return  insertOrig ( original1,  unifiedDiff) ; 
  } 
  
  public  static  List < String > diffString ( String  filePathOriginal,  String  filePathRevised)  { 
    
    List < String > =  null ; 
    
    List < String > =  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 > ,  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 > ,  List < String > )  { 
    List < String > =  new  ArrayList < > ( ) ; 
    
    List < List < String > > =  new  ArrayList < > ( ) ; 
    List < String > =  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 > =  new  ArrayList < > ( ) ; 
        twoList. addAll ( d) ; 
        diffList. add ( twoList) ; 
        d. clear ( ) ; 
        d. add ( u) ; 
        continue ; 
      } 
      if  ( i ==  unifiedDiff. size ( )  -  1 )  { 
        d. add ( u) ; 
        List < String > =  new  ArrayList < > ( ) ; 
        twoList. addAll ( d) ; 
        diffList. add ( twoList) ; 
        d. clear ( ) ; 
        break ; 
      } 
      d. add ( u) ; 
    } 
    
    for  ( int  i =  0 ;  i <  diffList. size ( ) ;  i++ )  { 
      List < String > =  diffList. get ( i) ; 
      List < String > =  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 > =  getRowMap ( simb) ; 
      if  ( null  !=  nexSimb)  { 
        Map < String ,  Integer > =  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 > ,  List < String > )  { 
    for  ( String  ins :  noChangeContent)  { 
      result. add ( ins) ; 
    } 
  } 
  
  public  static  Map < String ,  Integer > getRowMap ( String  str)  { 
    Map < String ,  Integer > =  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 > ,  int  start,  int  end)  { 
    List < String > =  new  ArrayList < > ( ) ; 
    if  ( original1. size ( )  >=  1  &&  start <=  end &&  end <  original1. size ( ) )  { 
      for  ( ;  start <=  end;  start++ )  { 
        list. add ( original1. get ( start) ) ; 
      } 
    } 
    return  list; 
  } 
}