文件对比8,单线程读,多线程对比,对比进度条,对比结果导出excel文件,已验收

  • 介绍
  • 项目结构预览
  • base
    • util
      • CompareThreadUtil
      • ExcelUtil
      • Md5
      • ReadFile2
      • Util
  • Controller
    • FileCompareController
  • enttity
    • Fc
    • MyExportExcel
    • ResponseForm
  • service
    • serviceimpl
  • helloWorldApplication

介绍

文件对比其实是某个大项目的一个小部分功能的实现,
为了实现这个功能,我思路与想法很多都直接以blog的形式写了出来,可能部分会有缺漏(自认为无伤大雅),
我把这个功能单独拆出来(已经将部分信息隐去,你可自定包结构引入),
你可以做成jar包在linux服务器上单独使用也可以结合到你的业务当中,
技术不复杂但各种有趣的点很多,无论是多线程应用,md5加密,文件读取,文件递归,全局变量的应用
进度条的实现,还是以excel的形式导出结果 。

项目结构预览

base

util

CompareThreadUtil

import java.io.File;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class CompareThreadUtil {public static int i;//当前文件个数private CountDownLatch latch;private CyclicBarrier barrier;private LinkedList linkedList = new LinkedList();//总private LinkedList<Fc> linkedList1 = new LinkedList<Fc>();//读取路径1中的所有的文件private LinkedList<Fc> linkedList2 = new LinkedList<Fc>();//读取路径2中的所有的文件private Lock lock = new ReentrantLock();private List listoneNot1 = new ArrayList<Fc>(); //存放数据一缺失的数据private List listoneNot2 = new ArrayList<Fc>(); //存放数据二缺失的数据private List listoneNot3 = new ArrayList<Fc>(); //存放数据二缺失的数据private Object numberLock = new Object();private boolean lockboo = false;private List<String> list;private File root1;private File root2;private String dirName1;private String dirName2;private ReadFile2 trFile1;private Boolean[] StopIt;public CompareThreadUtil(CountDownLatch latch, CyclicBarrier barrier,List list,List<Fc> listoneNot1, List<Fc> listoneNot2,List<Fc> listoneNot3, File root1, File root2,String dirName1, String dirName2, ReadFile2 trFile1, Boolean[] stop) {this.latch = latch;this.barrier = barrier;this.list = list;this.listoneNot1 = listoneNot1;this.listoneNot2 = listoneNot2;this.listoneNot3 = listoneNot3;this.root1 = root1;this.root2 = root2;this.dirName1 = dirName1;this.dirName2 = dirName2;this.trFile1 = trFile1;this.StopIt = stop;}public void addFileLevelAfter(int currentID, Integer percentagesum1, int[] i) {File[] file = new File[1];File f0File = null;try {while (true) {trFile1.getFileInfo(file);f0File = file[0];if (!StopIt[0] && f0File == null) {System.out.println("读取线程结束,线程" + currentID + "已获取不到文件,线程停止!");break;}if (f0File != null) {addPercent(i);NumberFormat numberFormat = NumberFormat.getNumberInstance();numberFormat.setMaximumFractionDigits(2);String result = numberFormat.format((float) i[0] / (float) percentagesum1 * 100);FileComparesServiceImpl.percentage1 = result + "%";FileComparesServiceImpl.syncCurrentName1 = f0File.getName();System.out.println("当前为检测线程" + currentID + "读取的文件为第" + i[0] + "个文件" + "文件名为" + f0File + "   文件总数为" + percentagesum1);System.out.println("此时百分比为" + FileComparesServiceImpl.percentage1);if (String.valueOf(f0File).startsWith(dirName1)) {File file2 = new File(f0File.toString().replace(dirName1, dirName2));if (file2.exists()) {if (f0File.lastModified() != file2.lastModified()) {Fc fc1 = new Fc();fc1.setType("两数据源对比发生修改的文件");fc1.setPath(f0File.getPath());fc1.setLastmodified(String.valueOf(f0File.lastModified()));fc1.setMd5(getMD5File(f0File));listoneNot3.add(fc1);}} else {Fc fc = new Fc();fc.setType("数据源1发生删除的文件");fc.setPath(f0File.getPath());fc.setLastmodified(String.valueOf(f0File.lastModified()));fc.setMd5(getMD5File(f0File));listoneNot1.add(fc);}} else {File file1 = new File(f0File.toString().replace(dirName2, dirName1));if (file1.exists()) {if (f0File.lastModified() != file1.lastModified()) {Fc fc1 = new Fc();fc1.setType("两数据源对比发生修改的文件");fc1.setPath(f0File.getPath());fc1.setLastmodified(String.valueOf(f0File.lastModified()));fc1.setMd5(getMD5File(f0File));listoneNot3.add(fc1);}} else {Fc fc = new Fc();fc.setType("数据源2发生删除的文件");fc.setPath(f0File.getPath());fc.setLastmodified(String.valueOf(f0File.lastModified()));fc.setMd5(getMD5File(f0File));listoneNot2.add(fc);}}}}} catch (Exception e) {e.printStackTrace();System.out.println("线程" + currentID + " 正常停止!");} finally {latch.countDown();}}public static synchronized void addPercent(int[] i) {try {i[0]++;} catch (Exception e) {e.printStackTrace();}}}

ExcelUtil

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.context.annotation.ComponentScan;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;public class ExcelUtil {/*** 导出并下载* * @param response*            response对象* @param data*            数据源(对象)* @param title*            每一列的标题* @param columns*            需要导出的字段* @param excelName*            excel名字*/public static void exportData(HttpServletResponse response, List<?> data, List<String> title, List<String> columns,String excelName) {response.setContentType("application/vnd.ms-excel");String codedFileName = null;OutputStream fOut = null;// 进行转码,使其支持中文文件名try {codedFileName = java.net.URLEncoder.encode(excelName + "(" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ")", "UTF-8");} catch (UnsupportedEncodingException e1) {e1.printStackTrace();}response.setHeader("content-disposition", "attachment;filename=" + codedFileName + ".xls");HSSFWorkbook wb = new HSSFWorkbook();MyExportExcel myExportExcel = new MyExportExcel();myExportExcel.setHssfWorkbook(wb);// 设置标题myExportExcel.setExcelTitle(excelName + "(" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ")",title.size()-1);// 设置列名myExportExcel.setNormalTwoRow(title);if (data.size() < 1) {myExportExcel.setNullData(columns.size()-1);} else {try {//导出数据myExportExcel.setExcelData2(data, columns);} catch (IllegalAccessException e) {e.printStackTrace();}}try {fOut = response.getOutputStream();wb.write(fOut);} catch (IOException e) {e.printStackTrace();} finally {try {fOut.flush();fOut.close();} catch (IOException e) {e.printStackTrace();}}}/*** @param response* @param data (map)* @param title* @param columns* @param excelName*/public static void exportData1(HttpServletResponse response, List<?> data, List<String> title, List<String> columns,String excelName) {response.setContentType("application/vnd.ms-excel");String codedFileName = null;OutputStream fOut = null;// 进行转码,使其支持中文文件名try {codedFileName = java.net.URLEncoder.encode(excelName + "(" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ")", "UTF-8");} catch (UnsupportedEncodingException e1) {e1.printStackTrace();}response.setHeader("content-disposition", "attachment;filename=" + codedFileName + ".xls");HSSFWorkbook wb = new HSSFWorkbook();MyExportExcel myExportExcel = new MyExportExcel();myExportExcel.setHssfWorkbook(wb);// 设置标题myExportExcel.setExcelTitle(excelName + "(" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ")",title.size()-1);// 设置列名myExportExcel.setNormalTwoRow(title);if (data.size() < 1) {myExportExcel.setNullData(columns.size()-1);} else {try {//导出数据myExportExcel.setExcelData3(data, columns);} catch (IllegalAccessException e) {e.printStackTrace();}}try {fOut = response.getOutputStream();wb.write(fOut);} catch (IOException e) {e.printStackTrace();} finally {try {fOut.flush();fOut.close();} catch (IOException e) {e.printStackTrace();}}}}

Md5


import java.io.File;
import java.io.FileInputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;/*** Md5工具类** @version 20161209*/
public class Md5 {/*** 加密字符串*/public static String stringToMd5(String str) throws Exception {StringBuffer userpass = new StringBuffer("");if (str != null && !str.equals("")) {MessageDigest md = MessageDigest.getInstance("MD5");md.update(str.getBytes());byte b[] = md.digest();int i;userpass = new StringBuffer("");for (int offset = 0; offset < b.length; offset++) {i = b[offset];if (i < 0)i += 256;if (i < 16)userpass.append("0");userpass.append(Integer.toHexString(i));}}return userpass.toString();}/*** 获取文件MD5*/public static String getMD5File(File file) {String inputFile = file.getPath();String result = "";// 缓冲区大小int bufferSize = 256 * 1024;FileInputStream fis = null;DigestInputStream dis = null;try {// 拿到一个MD5转换器MessageDigest md = MessageDigest.getInstance("MD5");// 使用DigestInputStreamfis = new FileInputStream(inputFile);dis = new DigestInputStream(fis, md);// read 过程中进行MD5处理,直到读完文件byte[] buffer = new byte[bufferSize];while (dis.read(buffer) > 0);// 获取最终的MessageDigestmd = dis.getMessageDigest();// 拿到结果,也是字节数组,包含16个元素byte[] resultByteArray = md.digest();// 同样,把字节组转换成字符串result = byteArrayToHex(resultByteArray);} catch (Exception e) {e.printStackTrace();} finally {try {dis.close();fis.close();} catch (Exception e) {e.printStackTrace();}}return result;}// 将字节数组转换成字符串private static String byteArrayToHex(byte[] b) {String hs = "";String stmp = "";for (int i = 0; i < b.length; i++) {stmp = (Integer.toHexString(b[i] & 0xFF));if (stmp.length() == 1) {hs = hs + "0" + stmp;} else {hs = hs + stmp;}if (i < b.length - 1) {hs = hs + "";}}return hs;}public static void main(String[] args) {File files = new File("F:\\学习资料\\Spring Cloud微服务实战.pdf");System.out.println(getMD5File(files));}
}

ReadFile2


import java.io.File;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class ReadFile2 {//    private static final Logger logger = Logger.getLogger(ReadFile.class);private CountDownLatch latch;private CyclicBarrier barrier;private LinkedList<File> linkedList = new LinkedList();//总private Lock lock = new ReentrantLock();private Object numberLock = new Object();private boolean lockboo = false;private List<String> list;private File root1;private File root2;private String dirName1;private String dirName2;private Boolean[] StopIt;public ReadFile2(CountDownLatch latch, CyclicBarrier barrier,List list,String dirName1, String dirName2,Boolean[] stop) {this.latch = latch;this.barrier = barrier;this.list = list;this.dirName1 = dirName1;this.dirName2 = dirName2;this.StopIt = stop;}// 读取文件信息public void readFile() {try {readFileInfo(new File(list.get(0)));readFileInfo(new File(list.get(1)));//            logger.info("读取文件线程正常停止!");System.out.println("读取文件线程正常停止!");} catch (Exception e) {System.out.println("错误信息!" + e);} finally {StopIt[0] = false;latch.countDown();}}private void readFileInfo(File root) {if (root.exists()) {if (root.isDirectory()) {File[] files = root.listFiles();if (files != null) {for (int i = 0; i < files.length; i++) {if (files[i].isFile()) {addFile(files[i]);} else if (files[i].isDirectory()) {readFileInfo(files[i]);}files[i] = null;}}files = null;} else if (root.isFile()) {addFile(root);}}}private void addFile(File file) {lock.lock();try {linkedList.addLast(file);} catch (Exception e) {System.out.println("添加文件出错:" + e);} finally {lock.unlock();
//            try {//                if (linkedList.size() >= 10000) {//                    synchronized (numberLock) {//                        lockboo = true;
//                        numberLock.wait();
//                    }
//                }
//            } catch (Exception e2) {                logger.error("锁出错:", e2);
//                System.out.println("锁出错" + e2);
//            }}}public void getFileInfo(File[] file) {lock.lock();try {file[0] = linkedList.pollFirst();if (lockboo && linkedList.size() <= 1000) {synchronized (numberLock) {lockboo = false;numberLock.notify();}}} catch (Exception e) {//            logger.error("获取文件出错:", e);System.out.println("获取文件出错:" + e);} finally {lock.unlock();}}}

Util


import eu.bitwalker.useragentutils.UserAgent;
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;public class Util implements FilenameFilter {private static final Logger logger = LoggerFactory.getLogger(Util.class);private static final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");private String suffix;public Util(String suffix) {super();this.suffix = suffix;}/*** 文件大小格式化** @param length 文件大小*/public static String fileSizeFormat(long length) {DecimalFormat df = new DecimalFormat("#0.0");float size = (float) length / 1024;String sumFilesize = "";if (size >= 0 && size < 1) {sumFilesize = length + " B";} else if (size >= 1 && size < 1024) {sumFilesize = df.format(size) + " K";} else if (size >= 1024) {size = size / 1024;if (size >= 1 && size < 1024) {sumFilesize = df.format(size) + " M";} else if (size >= 1024 && size < 1048576) {size = size / 1024;sumFilesize = df.format(size) + " G";} else if (size >= 1048576) {size = size / 1024 / 1024;sumFilesize = df.format(size) + " T";}}return sumFilesize;}/*** 文件大小格式化  传入的单位是GB** @param length 文件大小*/public static String fileSizeFormat2(long length) {DecimalFormat df = new DecimalFormat("#0.0");float size = (float) length / 1024;String sumFilesize = "";if (size >= 0 && size < 1) {sumFilesize = length + " G";} else if (size >= 1) {sumFilesize = df.format(size) + " T";}return sumFilesize;}/*** 文件拷贝** @param f1Path 源路径* @param f2Path 目标路径*/public static boolean fileCopy(String f1Path, String f2Path) {BufferedInputStream bis = null;BufferedOutputStream bos = null;File f1 = null;File f2 = null;int outputSize = 1024000;// 默认1Mboolean boo = false;try {f1 = new File(f1Path);f2 = new File(f2Path);File pfile = new File(f2.getParent());if (!pfile.exists()) {pfile.mkdirs();}if (f1.length() > 104857600) {outputSize = 10240000; // 文件大于100M,修改outputSize为10240000}FileInputStream fis = new FileInputStream(f1);FileOutputStream fos = new FileOutputStream(f2);bis = new BufferedInputStream(fis);bos = new BufferedOutputStream(fos);byte[] b = new byte[outputSize];int len = 0;while ((len = bis.read(b, 0, b.length)) != -1) {bos.write(b, 0, len);}bos.flush();boo = true;} catch (Exception e) {boo = false;logger.error("文件" + f1Path + "拷贝失败,原因:", e);} finally {try {if (bos != null)bos.close();if (bis != null)bis.close();} catch (IOException e) {boo = false;e.printStackTrace();}if (boo) {// 修改时间戳boo = f2.setLastModified(f1.lastModified());}}return boo;}/*** 文件拷贝 20181110** @param f1File 源路径* @param f2File 目标路径*/public static boolean fileCopyNew(File f1File, File f2File) {BufferedInputStream bis = null;BufferedOutputStream bos = null;int outputSize = 1024000;// 默认1Mboolean boo = false;try {File pfile = f2File.getParentFile();if (!pfile.exists()) {pfile.mkdirs();}pfile = null; //回收对象if (f1File.length() > 104857600) {outputSize = 10240000; // 文件大于100M,修改outputSize为10240000}FileInputStream fis = new FileInputStream(f1File);FileOutputStream fos = new FileOutputStream(f2File);bis = new BufferedInputStream(fis);bos = new BufferedOutputStream(fos);byte[] b = new byte[outputSize];int len = 0;while ((len = bis.read(b, 0, b.length)) != -1) {bos.write(b, 0, len);}bos.flush();boo = true;} catch (Exception e) {boo = false;logger.error("文件" + f1File.getPath() + "拷贝失败,原因:", e);} finally {try {if (bos != null)bos.close();if (bis != null)bis.close();} catch (IOException e) {boo = false;e.printStackTrace();}if (boo) {// 修改时间戳boo = f2File.setLastModified(f1File.lastModified());}}return boo;}/*** 下载打包的文件** @param file* @param response* @param isDelete 是否删除源文件*/public static void downloadZip(File file, HttpServletResponse response, boolean isDelete) {BufferedInputStream bis = null;BufferedOutputStream bos = null;boolean boo = false;try {response.reset();response.setCharacterEncoding("ISO8859-1");// 先去掉文件名称中的空格,然后转换编码格式为utf-8,保证不出现乱码,这个文件名称用于浏览器的下载框中自动显示的文件名response.setHeader("Content-Disposition", "attachment;filename=" + new String(file.getName().getBytes("gb2312"), "ISO8859-1"));response.setContentType("application/octet-stream");response.setHeader("Connection", "close");response.setContentLength((int) file.length());bis = new BufferedInputStream(new FileInputStream(file.getPath()));bos = new BufferedOutputStream(response.getOutputStream());byte[] b = new byte[10240];int len = 0;while ((len = bis.read(b, 0, b.length)) != -1) {bos.write(b, 0, len);}bos.flush();boo = true;} catch (Exception e) {boo = false;} finally {try {if (bos != null)bos.close();if (bis != null)bis.close();} catch (IOException e) {boo = false;}if (boo && isDelete) {file.delete();}}}/*** 文件打包** @param filePathList 需要打包的文件路径集合* @param targetPath   目的路径* @param password     打包密码*/public static boolean collectFiles(List<String> filePathList, String targetPath, String password) {try {File targetPathParent = new File(new File(targetPath).getParent());if (!targetPathParent.exists()) {targetPathParent.mkdirs();}ZipParameters parameters = new ZipParameters();parameters.setCompressionMethod(Zip4jConstants.COMP_STORE);parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_FASTEST);if (password != null && !password.equals("")) {parameters.setEncryptFiles(true);parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);parameters.setPassword(password);}ZipFile zipFile = new ZipFile(targetPath);zipFile.setFileNameCharset("gbk");for (String ss : filePathList) {File file = new File(ss);if (file.exists() && file.isDirectory()) {zipFile.addFolder(file, parameters);} else if (file.exists() && file.isFile()) {zipFile.addFile(file, parameters);}}} catch (ZipException e) {logger.error("文件打包失败,原因:", e);return false;}return true;}/*** 文件解压** @param sourceFile 需要解压的文件路径* @param targetPath 目的路径*/public static boolean extractFile(String sourceFile, String targetPath) {try {ZipFile zFile = new ZipFile(sourceFile);zFile.setFileNameCharset("GBK");if (!zFile.isValidZipFile()) { // 验证.zip文件是否合法,包括文件是否存在、是否为zip文件、是否被损坏等throw new ZipException("压缩文件不合法,可能被损坏.");}File destDir = new File(targetPath); // 解压目录if (destDir.isDirectory() && !destDir.exists()) {destDir.mkdir();}zFile.extractAll(targetPath);} catch (ZipException e) {logger.error("文件解压失败,原因:", e);return false;}return true;}/*** 文件夹删除** @param filePath 需要删除的文件夹路径*/public static boolean deleteFiles(String filePath) {boolean flag = true;File dirFile = new File(filePath);if (!dirFile.exists() || !dirFile.isDirectory()) {return false;}File[] files = dirFile.listFiles();for (int i = 0; i < files.length; i++) {if (files[i].isFile()) {File file = new File(files[i].getAbsolutePath());flag = file.delete();if (!flag)break;} else {flag = deleteFiles(files[i].getAbsolutePath());if (!flag)break;}}if (!flag)return false;// 删除当前目录if (dirFile.delete()) {return true;} else {return false;}}/*** 文件剪切** @param source 源文件* @param target 目标文件*/public static boolean fileShear(String source, String target) {File sourceFile = new File(source);boolean flag = true;if (!sourceFile.exists()) {return false;}if (!sourceFile.isDirectory()) {if (fileCopy(source, target)) {flag = sourceFile.delete();} else {flag = false;}return flag;} else {File[] files = sourceFile.listFiles();for (int i = 0; i < files.length; i++) {String filesPath = files[i].getPath().replace("\\", "/");if (files[i].isFile()) {if (fileCopy(filesPath, filesPath.replace(source, target))) {flag = files[i].delete();} else {flag = false;}if (!flag)break;} else {flag = fileShear(filesPath, filesPath.replace(source, target));if (!flag)break;}}if (!flag)return false;// 删除当前目录if (sourceFile.delete()) {return true;} else {return false;}}}/*** 计算百分比** @param dividend 被除数* @param divisor  除数*//*public static String getProgressbar(int dividend, int divisor) {try {int a = dividend / (divisor / 100);if (a >= 100) {a = 100;}return a + "";} catch (Exception e) {return "0";}}*//*** @Description :* @Params [dividend, divisor]* @Return: java.lang.String*/public static String getProgressbar(int dividend, int divisor) {if (divisor != 0) {NumberFormat numberFormat = NumberFormat.getInstance();numberFormat.setMaximumFractionDigits(2);return numberFormat.format((float) dividend / (float) divisor * 100);} else {return "0";}}/*** 获取文件后缀名*/public static String getFileExtension(File file) {String fileName = file.getName();if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0) {return fileName.substring(fileName.lastIndexOf(".") + 1);} else {return "";}}/*** @return* @Description 判断是否有汉字* @Date 上午 9:05 2019/12/30 0030* @Param**/public static boolean isChinese(String countname) {Pattern p = Pattern.compile("[\u4e00-\u9fa5]");Matcher m = p.matcher(countname);if (m.find()) {return true;}return false;}/*** 文件大小格式化** @param length 文件大小*/public static String fileSizeFormatToG(double length) {DecimalFormat df = new DecimalFormat("#0.0");double size = length / 1024 / 1024 / 1024;String sumFilesize = df.format(size);return sumFilesize;}/*** @return* @Description //备份软件生成ID的工具类* @Date 上午 9:50 2019/11/8 0008* @Param**/public static String creatId() {UUID uuid = UUID.randomUUID();return uuid.toString();}/*** @Auther: 雷硕* @Date: 2018/1/23 0014 16:11* @Description:百分比转换UTIL num1除数, num2被除数*/public static String transform(Integer num1, Integer num2) {String result;// 创建一个数值格式化对象if (num1 != 0 && num2 != 0) {NumberFormat numberFormat = NumberFormat.getInstance();// 设置精确到小数点后2位numberFormat.setMaximumFractionDigits(2);result = numberFormat.format((float) num1 / (float) num2 * 100);} else {result = "0";}return result;}/*** @Auther: 雷硕* @Date: 2018/1/23 0014 16:11* @Description:百分比转换UTIL num1除数, num2被除数*/public static String transform2(Long num1, Long num2) {String result;// 创建一个数值格式化对象if (num1 != 0 && num2 != 0) {NumberFormat numberFormat = NumberFormat.getInstance();// 设置精确到小数点后2位numberFormat.setMaximumFractionDigits(0);result = numberFormat.format((float) num1 / (float) num2 * 100);} else {result = "0";}return result;}public static double div(double d1, double d2, int len) {// 进行除法运算BigDecimal b1 = new BigDecimal(d1);BigDecimal b2 = new BigDecimal(d2);return b1.divide(b2, len, BigDecimal.ROUND_HALF_UP).doubleValue();}//文件夹剪切public static void cutDirOrFile(String sourePath, String originalPath, String recyclePath) {File file = new File(sourePath);File[] files = file.listFiles();for (File file2 : files) {if (file2.isFile()) {Util.fileCopyNew(file2, new File(file2.toString().replace("\\", "/").replace(originalPath, recyclePath)));} else if (file2.isDirectory()) {cutDirOrFile(file2.toString(), originalPath, recyclePath);}}}/*** 树形结构** @param paths* @param fileArray* @param depotid* @param flag* @return*/public static JSONArray readFolderToTree(String paths, JSONArray fileArray, String depotid, String flag) {File file = new File(paths);String[] filelist = file.list();JSONArray jsonArray = new JSONArray();for (int i = 0; i < filelist.length; i++) {JSONObject fileJson = new JSONObject();File readfile = new File(paths + "/" + filelist[i]);if (readfile.isDirectory()) {String filepaths = readfile.getPath().replaceAll("\\\\", "/");if (!filepaths.endsWith("/")) {filepaths = filepaths + "/";}fileJson.put("id", filepaths);fileJson.put("pId", paths);fileJson.put("name", readfile.getName());fileJson.put("state", "closed");fileJson.put("isParent", "true");JSONObject attributes = new JSONObject();attributes.put("filepath", filepaths);attributes.put("depotid", depotid);attributes.put("flag", flag);fileJson.put("attributes", attributes);jsonArray.add(fileJson);}}fileArray.addAll(jsonArray);return fileArray;}//生成批次编号
//    public static JSONObject selectFillData(String curr) {//        JSONObject obj = new JSONObject();
//        if (StringUtils.isEmpty(curr)) {//            curr = DateUtils.getYearMonthDay2() + "00001";
//        } else {//            curr = curr.substring(8);
//            int news = Integer.parseInt(curr) + 1;
//            curr = String.valueOf(news);
//            switch (curr.length()) {//                case 4:
//                    curr = "0" + curr;
//                    break;
//                case 3:
//                    curr = "00" + curr;
//                    break;
//                case 2:
//                    curr = "000" + curr;
//                    break;
//                case 1:
//                    curr = "0000" + curr;
//            }
//
//            curr = DateUtils.getYearMonthDay2() + curr;
//
//        }
//
//        obj.put("pcbh", curr);
//        return obj;
//    }@Overridepublic boolean accept(File file, String name) {return !name.endsWith(suffix);}//截取zip文件夹的名称public static String subString(String path) {//      String path="/home/henry/Desktop/1.txt";String oo = path.substring(path.lastIndexOf("/", path.lastIndexOf("/") - 1) + 1);return oo.substring(0, oo.lastIndexOf("/"));}//不足八位,补足八位public static String complementEight(Object a) {String result = a + "";if (!(a instanceof Integer)) {return result;}if (a.toString().length() < 8) {Integer cha = 8 - a.toString().length();for (int i = 0; i < cha; i++) {result = "0" + result;}}return result;}/*** 获取加密密钥*/@SuppressWarnings("static-access")public static String getKey() {String key = "";//        com.softkey.jsyunew6 j9 = new com.softkey.jsyunew6();
//        String DevicePath = j9.FindPort(0);
//
//        if (j9.get_LastError() != 0) {            logger.info("未在服务器上找到加密锁!");
//        } else {//            j9.YRead((short) 0, (short) 1, "98A135F3", "37997F31", DevicePath);
//            short address = 1;// 要读取的字符串在加密锁中储存的起始地址
//            short len = j9.GetBuf(0);// 注意这里的6是长度,要与写入的字符串的长度相同
//            key = j9.YReadString(address, len, "98A135F3", "37997F31", DevicePath);
//
//            if (!key.substring(0, key.indexOf("|")).equals("DMS")) {//                key = "";
//            } else {//                key = key.substring(key.lastIndexOf("|") + 1, key.length());
//            }
//        }return "77NEdEJJK3d396b4wx549LDY56S75bK1";}public static JSONObject getFileInfo(String filefullpath) {File file = new File(filefullpath);String filename;String extname = "";String filepath;int nameindex = filefullpath.lastIndexOf("/");filepath = filefullpath.substring(0, nameindex + 1);filename = filefullpath.substring(nameindex + 1);int extindex = filename.lastIndexOf(".");if (extindex != -1) {extname = filename.substring(extindex + 1);filename = filename.substring(0, extindex);}JSONObject obj = new JSONObject();obj.put("filepath", filepath);obj.put("filename", filename);obj.put("extname", extname);return obj;}public static JSONObject getMessage(HttpServletRequest request){UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));String brower = userAgent.getBrowser().getName();String system = userAgent.getOperatingSystem().getName();JSONObject jsonObject=new JSONObject();jsonObject.put("system",system);jsonObject.put("browser",brower);return jsonObject;}/*** 读取当前文件夹第一层的文件和文件夹** @param filepath*            文件夹路径* @param array*            返回的结果集合*/public static void readCurrentFirstFile(String filepath, List<String> array) {File file = new File(filepath);String[] filelist = file.list();for (int i = 0; i < filelist.length; i++) {File readfile = new File(filepath + "/" + filelist[i]);if (!readfile.isHidden()) {array.add(readfile.getAbsolutePath());}}}//获取CPU核心数public static Integer getCPUnum(){int i = Runtime.getRuntime().availableProcessors();return i;}/*** @param s 源文件* @param t 复制到的新文件*/public static boolean fileChannelCopy(File s, File t) {FileInputStream fi = null;FileOutputStream fo = null;FileChannel in = null;FileChannel out = null;boolean boo = true;int GB = 1024 * 1024 * 1024;//定义GB的计算常量try {File pfile = new File(t.getParent());if (!pfile.exists()) {pfile.mkdirs();}fi = new FileInputStream(s);fo = new FileOutputStream(t);in = fi.getChannel();//得到对应的文件通道out = fo.getChannel();//得到对应的文件通道if (in.size() / GB >= 2) {ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024);while (in.read(buffer) != -1) {buffer.flip();out.write(buffer);buffer.clear();}} else {in.transferTo(0, in.size(), out);//连接两个通道,并且从in通道读取,然后写入out通道}} catch (IOException e) {boo = false;logger.error("文件" + s.getPath() + "拷贝失败,原因:", e);} finally {try {fi.close();in.close();fo.close();out.close();} catch (IOException e) {e.printStackTrace();}if (boo) {// 修改时间戳boo = t.setLastModified(s.lastModified());}}return boo;}/*** 获取文件后缀名*/public static String getFileExtensions(String fileName) {if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0) {return fileName.substring(fileName.lastIndexOf(".") + 1);} else {return "";}}}

Controller

FileCompareController

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.taiyusoft.tydms.base.util.ExcelUtil;
import com.taiyusoft.tydms.entity.Fc;
import com.taiyusoft.tydms.entity.ResponseForm;
import com.taiyusoft.tydms.service.FileComparesService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;/**** @Param* @return**/
@RestController
@RequestMapping("/fileComparesimple")
public class FileCompareController {private Logger logger = LoggerFactory.getLogger(getClass());@Autowiredprivate FileComparesService fileComparesService;//调用文件对比@RequestMapping("/selectfileComparesimple")public void fileComparesimple(String firstpath, String secondpath) {long time1 = System.currentTimeMillis();File file1 = new File(firstpath);File file2 = new File(secondpath);try {if (file1.isFile() || file1.isDirectory() && file2.isFile() || file2.isDirectory()) {fileComparesService.fileComparesimple(firstpath.replace("/","\\"), secondpath.replace("/","\\"));}long time2 = System.currentTimeMillis();int time = (int) ((time2 - time1) / 1000);System.out.println("执行了:" + time + "秒!");} catch (Exception e) {e.printStackTrace();}}/*** 进度条初始化** @return*/@RequestMapping("/fileComparesinit")public ResponseForm fileComparesinit(String firstpath, String secondpath) {ResponseForm responseForm = new ResponseForm();Integer sum = 0;try {sum = fileComparesService.initPercentage(firstpath, secondpath);JSONObject jsonObject = new JSONObject();jsonObject.put("sum", sum);if (sum > 0) {responseForm.setCode("200");responseForm.setData(jsonObject);responseForm.setMessage(ResponseForm.message.SUCCESS);} else {responseForm.setCode("401");responseForm.setMessage(ResponseForm.message.FAIL);}} catch (Exception e) {e.printStackTrace();System.out.println(e);responseForm.setCode("402");responseForm.setMessage(ResponseForm.message.FAIL);}return responseForm;}/*** 文件对比时间过长时,出现该当前文件进度条百分比*/@RequestMapping("/fileComparesimplePercentage")public ResponseForm fileComparesimplePercentage() {ResponseForm responseForm = new ResponseForm();JSONObject jsonObject;try {jsonObject = fileComparesService.fileComparesimplePercentage();responseForm.setData(jsonObject);responseForm.setCode("200");responseForm.setMessage(ResponseForm.message.SUCCESS);} catch (Exception e) {responseForm.setCode("400");responseForm.setMessage(ResponseForm.message.FAIL);}return responseForm;}/*** 文件处理时间过长时,专门获取文件对比结果** @return*/@RequestMapping("/getfileCompares")public ResponseForm getfileCompares() {ResponseForm responseForm = new ResponseForm();JSONObject jsonObject;try {jsonObject = fileComparesService.getfileCompares();responseForm.setData(jsonObject);responseForm.setCode("200");responseForm.setMessage(ResponseForm.message.SUCCESS);} catch (Exception e) {responseForm.setCode("400");responseForm.setMessage(ResponseForm.message.FAIL);}return responseForm;}/*** 导出excel** @return*/@RequestMapping("/exportExcel")@ResponseBodypublic String exportExcel(HttpServletResponse response) {ResponseForm responseForm = new ResponseForm();String querystr = "";String starTime = "";String endTime = "";JSONObject jsonObject;responseForm = getfileCompares();ArrayList<Fc> listoneNot1 = new ArrayList<>();ArrayList<Fc> listoneNot2 = new ArrayList<>();ArrayList<Fc> listoneNot3 = new ArrayList<>();JSONObject data = new JSONObject();listoneNot1 = (ArrayList<Fc>) ((JSONObject) responseForm.getData()).get("数据源1发生删除的文件");listoneNot2 = (ArrayList<Fc>) ((JSONObject) responseForm.getData()).get("数据源2发生删除的文件");listoneNot3 = (ArrayList<Fc>) ((JSONObject) responseForm.getData()).get("两数据源对比发生修改的文件");ArrayList<Fc> fcs = new ArrayList<>();fcs.addAll(listoneNot1);fcs.addAll(listoneNot2);fcs.addAll(listoneNot3);
for (Fc fc : fcs) {System.out.println(fc);
}List<String> list1 = new ArrayList<>();list1.add("文件类别");list1.add("路径");list1.add("最后修改时间");list1.add("md5");List<String> list2 = new ArrayList<>();list2.add("type");list2.add("path");list2.add("lastmodified");list2.add("md5");ExcelUtil.exportData(response, fcs, list1, list2, "对比文件结果");try {response.getWriter().print("导出成功");} catch (IOException e) {e.printStackTrace();}return null;}
}

enttity

Fc


public class Fc {String type;String path;String lastmodified;String md5;public String getPath() {return path;}public void setPath(String path) {this.path = path;}public String getLastmodified() {return lastmodified;}public void setLastmodified(String lastmodified) {this.lastmodified = lastmodified;}public String getMd5() {return md5;}public void setMd5(String md5) {this.md5 = md5;}public String getType() {return type;}public void setType(String type) {this.type = type;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Fc fc = (Fc) o;if (path != null ? !path.equals(fc.path) : fc.path != null) return false;if (lastmodified != null ? !lastmodified.equals(fc.lastmodified) : fc.lastmodified != null) return false;return md5 != null ? md5.equals(fc.md5) : fc.md5 == null;}@Overridepublic int hashCode() {int result = path != null ? path.hashCode() : 0;result = 31 * result + (lastmodified != null ? lastmodified.hashCode() : 0);result = 31 * result + (md5 != null ? md5.hashCode() : 0);return result;}
}

MyExportExcel

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.util.CellRangeAddress;import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;public class MyExportExcel {private HSSFWorkbook hssfWorkbook;private HSSFSheet sheet;/*** @return the hssfWorkbook*/public HSSFWorkbook getHssfWorkbook() {return hssfWorkbook;}/*** @return the sheet*/public HSSFSheet getSheet() {return sheet;}/*** @param sheet*            the sheet to set*/public void setSheet(HSSFSheet sheet) {this.sheet = sheet;}/*** @param hssfWorkbook*            the hssfWorkbook to set*/public void setHssfWorkbook(HSSFWorkbook hssfWorkbook) {this.hssfWorkbook = hssfWorkbook;}/*** * @Description:设置标题* @return void 返回类型*/@SuppressWarnings("deprecation")public void setExcelTitle(String title, int colSum) {this.sheet = hssfWorkbook.createSheet(title);// 创建Excel工作表对象// 设置列宽for (int i = 0; i <= colSum; i++) {sheet.setColumnWidth((short) i, (short) 7250);}HSSFCellStyle cellStyle = hssfWorkbook.createCellStyle();cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 指定单元格居中对齐cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 指定单元格垂直居中对齐cellStyle.setWrapText(true);// 指定单元格自动换行// 设置单元格背景色cellStyle.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index);cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);// 设置单元格字体HSSFFont font = hssfWorkbook.createFont();font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);font.setFontName("宋体");font.setFontHeight((short) 300);cellStyle.setFont(font);// cellStyle.setBottomBorderColor(HSSFColor.GREEN.index); // 设置单元格的边框颜色.// cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);// cellStyle.setLeftBorderColor(HSSFColor.GREEN.index);// cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);// cellStyle.setRightBorderColor(HSSFColor.GREEN.index);// cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);// cellStyle.setTopBorderColor(HSSFColor.GREEN.index);HSSFRow row = sheet.createRow(0);// 设置第一行HSSFCell cell = row.createCell(0);// 设置行宽row.setHeight((short) 600);// 定义单元格为字符串类型cell.setCellType(HSSFCell.ENCODING_UTF_16);cell.setCellValue(new HSSFRichTextString(title));// 指定合并区域sheet.addMergedRegion(new CellRangeAddress(0, (short) 0, 0, (short) colSum));cell.setCellStyle(cellStyle);}/*** * @Description:没有数据时excel* @return void 返回类型*/public void setNullData(int colSum) {HSSFCellStyle cellStyle = hssfWorkbook.createCellStyle();cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 指定单元格居中对齐cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 指定单元格垂直居中对齐cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);cellStyle.setBottomBorderColor(HSSFColor.BLACK.index); // 设置单元格的边框颜色.cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);cellStyle.setLeftBorderColor(HSSFColor.BLACK.index);cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);cellStyle.setRightBorderColor(HSSFColor.BLACK.index);cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);cellStyle.setTopBorderColor(HSSFColor.BLACK.index);HSSFRow row = sheet.createRow(2);for (int i = 0; i <= colSum; i++) {HSSFCell cell2 = row.createCell(i);cell2.setCellStyle(cellStyle);}// 设置第一行HSSFCell cell = row.createCell(0);// 设置行宽row.setHeight((short) 600);// 定义单元格为字符串类型cell.setCellType(HSSFCell.ENCODING_UTF_16);cell.setCellValue(new HSSFRichTextString("没有数据"));// 指定合并区域sheet.addMergedRegion(new CellRangeAddress((short) 2, (short) 0, 2, (short) colSum));cell.setCellStyle(cellStyle);}/*** * @Description: 设置列名* @return void 返回类型*/public void setNormalTwoRow(List<String> columHeader) {HSSFRow row1 = sheet.createRow(1);row1.setHeight((short) 400);HSSFCellStyle cellStyle = hssfWorkbook.createCellStyle();cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 指定单元格居中对齐cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 指定单元格垂直居中对齐// HSSFCell cell3 = null;cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);cellStyle.setBottomBorderColor(HSSFColor.BLACK.index); // 设置单元格的边框颜色.cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);cellStyle.setLeftBorderColor(HSSFColor.BLACK.index);cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);cellStyle.setRightBorderColor(HSSFColor.BLACK.index);cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);cellStyle.setTopBorderColor(HSSFColor.BLACK.index);HSSFFont font = hssfWorkbook.createFont();font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);cellStyle.setFont(font);for (int i = 0; i < columHeader.size(); i++) {HSSFCell cell3 = row1.createCell(i);cell3.setCellType(HSSFCell.ENCODING_UTF_16);cell3.setCellStyle(cellStyle);cell3.setCellValue(new HSSFRichTextString(columHeader.get(i)));}}/*** 根据方法调用顺序存入excel* * @param data*            包含泛型的list* @param method*            方法名*/public void setExcelData(List<?> data, List<String> method) {HSSFCellStyle cellStyle = hssfWorkbook.createCellStyle();cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);cellStyle.setBottomBorderColor(HSSFColor.BLACK.index); // 设置单元格的边框颜色.cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);cellStyle.setLeftBorderColor(HSSFColor.BLACK.index);cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);cellStyle.setRightBorderColor(HSSFColor.BLACK.index);cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);cellStyle.setTopBorderColor(HSSFColor.BLACK.index);try {for (int j = 0; j < data.size(); j++) {HSSFRow row = sheet.createRow(2 + j);// System.out.println(data.get(j));Class<?> clazz = data.get(j).getClass();for (int i = 0; i < method.size(); i++) {HSSFCell cell = row.createCell(i);cell.setCellType(HSSFCell.ENCODING_UTF_16);cell.setCellStyle(cellStyle);java.lang.reflect.Method m = clazz.getMethod(method.get(i));if (m.invoke(data.get(j)) != null) {cell.setCellValue(m.invoke(data.get(j)).toString());} else {cell.setCellValue("");}}}} catch (NoSuchMethodException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}/*** 给Excel单元格绑定数据* * @param list*            数据Data* @param colname*            字段名* @throws IllegalAccessException*/public void setExcelData2(List<?> list, List<String> colname) throws IllegalAccessException {HSSFCellStyle cellStyle = hssfWorkbook.createCellStyle();cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);cellStyle.setBottomBorderColor(HSSFColor.BLACK.index); // 设置单元格的边框颜色.cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);cellStyle.setLeftBorderColor(HSSFColor.BLACK.index);cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);cellStyle.setRightBorderColor(HSSFColor.BLACK.index);cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);cellStyle.setTopBorderColor(HSSFColor.BLACK.index);for (int j = 0; j < list.size(); j++) {HSSFRow row = sheet.createRow(2 + j);// System.out.println(list.get(j).toString());Map<String, Object> map;//如果传过来的数据类型是一个hashmapif(list.get(j).getClass().equals(HashMap.class)){map = (Map<String, Object>)list.get(j);//如果传过来的数据类型是一个实体类}else {map = objectToMap(list.get(j));System.out.println(map.toString());}System.out.println(map.toString());for (int i = 0; i < colname.size(); i++) {HSSFCell cell = row.createCell(i);cell.setCellType(HSSFCell.ENCODING_UTF_16);cell.setCellStyle(cellStyle);Object object = map.get(colname.get(i));if (object == null) {cell.setCellValue("");} else {cell.setCellValue(new HSSFRichTextString(object.toString()));}}}}/*** 给Excel单元格绑定数据* * @param list*            数据Data* @param colname*            字段名* @param startnum*            起始位置* @throws IllegalAccessException*/public void setExcelData2(List<?> list, List<String> colname, int startnum) throws IllegalAccessException {HSSFCellStyle cellStyle = hssfWorkbook.createCellStyle();cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);cellStyle.setBottomBorderColor(HSSFColor.BLACK.index); // 设置单元格的边框颜色.cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);cellStyle.setLeftBorderColor(HSSFColor.BLACK.index);cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);cellStyle.setRightBorderColor(HSSFColor.BLACK.index);cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);cellStyle.setTopBorderColor(HSSFColor.BLACK.index);for (int j = startnum; j < list.size(); j++) {HSSFRow row = sheet.createRow(2 + j);// System.out.println(list.get(j).toString());Map<String, Object> map = objectToMap(list.get(j));for (int i = 0; i < colname.size(); i++) {HSSFCell cell = row.createCell(i);cell.setCellType(HSSFCell.ENCODING_UTF_16);cell.setCellStyle(cellStyle);Object object = map.get(colname.get(i));if (object == null) {cell.setCellValue("");} else {cell.setCellValue(new HSSFRichTextString(object.toString()));}}}}/*** 给Excel单元格绑定数据* * @param list*            数据Data* @param colname*            字段名* @param change*            起始位置* @throws IllegalAccessException*/public void setExcelData2(List<?> list, List<String> colname, Map<String, Map<String, String>> change)throws IllegalAccessException {HSSFCellStyle cellStyle = hssfWorkbook.createCellStyle();cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);cellStyle.setBottomBorderColor(HSSFColor.BLACK.index); // 设置单元格的边框颜色.cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);cellStyle.setLeftBorderColor(HSSFColor.BLACK.index);cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);cellStyle.setRightBorderColor(HSSFColor.BLACK.index);cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);cellStyle.setTopBorderColor(HSSFColor.BLACK.index);for (int j = 0; j < list.size(); j++) {HSSFRow row = sheet.createRow(2 + j);// System.out.println(list.get(j).toString());Map<String, Object> map = objectToMap(list.get(j));for (int i = 0; i < colname.size(); i++) {HSSFCell cell = row.createCell(i);cell.setCellType(HSSFCell.ENCODING_UTF_16);cell.setCellStyle(cellStyle);Object object = map.get(colname.get(i));if (object == null) {cell.setCellValue("");} else {for (Entry<String, Map<String, String>> eny : change.entrySet()) {String fname = eny.getKey();Map<String, String> fval = eny.getValue();if (fname.equals(colname.get(i))) {cell.setCellValue(new HSSFRichTextString(fval.get(object.toString())));} else {cell.setCellValue(new HSSFRichTextString(object.toString()));}}// if (change.get(colname.get(i)) != null) {// Map<String,String> val= change.get(colname.get(i));// cell.setCellValue(new// HSSFRichTextString(val.get(object.toString())));// } else {// cell.setCellValue(new// HSSFRichTextString(object.toString()));// }}}}}/*** @param list*      list本身就是map* @param colname*          列名* @throws IllegalAccessException*/public void setExcelData3(List<?> list, List<String> colname) throws IllegalAccessException {HSSFCellStyle cellStyle = hssfWorkbook.createCellStyle();cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);cellStyle.setBottomBorderColor(HSSFColor.BLACK.index); // 设置单元格的边框颜色.cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);cellStyle.setLeftBorderColor(HSSFColor.BLACK.index);cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);cellStyle.setRightBorderColor(HSSFColor.BLACK.index);cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);cellStyle.setTopBorderColor(HSSFColor.BLACK.index);for (int j = 0; j < list.size(); j++) {HSSFRow row = sheet.createRow(2 + j);// System.out.println(list.get(j).toString());Map<String, String> map = (Map<String, String>) list.get(j);System.out.println(map.toString());for (int i = 0; i < colname.size(); i++) {HSSFCell cell = row.createCell(i);cell.setCellType(HSSFCell.ENCODING_UTF_16);cell.setCellStyle(cellStyle);Object object = map.get(colname.get(i));if (object == null) {cell.setCellValue("");} else {cell.setCellValue(new HSSFRichTextString(object.toString()));}}}}/*** Object转Map(包含父类的属性)* * @param obj* @return*/public static Map<String, Object> objectToMap(Object obj) {Map<String, Object> reMap = new HashMap<String, Object>();if (obj == null)return null;try {Class<?> objClass = obj.getClass();while (objClass != null) {Field[] fields = objClass.getDeclaredFields();for (int i = 0; i < fields.length; i++) {try {Field f = objClass.getDeclaredField(fields[i].getName());f.setAccessible(true);Object o = f.get(obj);reMap.put(fields[i].getName(), o);} catch (NoSuchFieldException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}objClass = objClass.getSuperclass();}} catch (SecurityException e) {e.printStackTrace();}return reMap;}}

ResponseForm

import java.io.Serializable;/**
* 这个类是根据layui接收数据的格式来定义的,
* private Object data; 存放的JSON数据
* private String code; , layui规定的格式, 需要在JSON数据前面有一个code字符创的状态码  code:0  , 我们这里固定返回200 , 前端会自动检验并且转换为0
* private message message; 这里是返回的信息, 在JSON数据的后面 , 成功就是SUCCESS , 失败就是FAIL, 这是layui解析表格固定JSON字符串的格式
* private Integer total; 这个属性是layui数据表格在展示分页数据的时候 , 需要的一个参数.我们后台把数据分页后,返回这个参数.
*
*/
public class ResponseForm implements Serializable {//返回的数据private Object data;//返回的状态码,200表示成功,400表示失败private String code;//返回的信息,成功失败private message message;//分页总数private Integer total;//每页数据量的参数名,默认:limitprivate Integer limit;public Integer getLimit() {return limit;}public void setLimit(Integer limit) {this.limit = limit;}public enum message {SUCCESS,FAIL}public ResponseForm() {}public ResponseForm(Object data, String code, ResponseForm.message message, Integer total) {this.data = data;this.code = code;this.message = message;this.total = total;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}public String getCode() {return code;}public void setCode(String code) {this.code = code;}public ResponseForm.message getMessage() {return message;}public void setMessage(ResponseForm.message message) {this.message = message;}public Integer getTotal() {return total;}public void setTotal(Integer total) {this.total = total;}
}

service


import com.alibaba.fastjson.JSONObject;public interface FileComparesService {void fileComparesimple(String firstpath, String secondpath);Integer initPercentage(String firstpath, String secondpath);JSONObject fileComparesimplePercentage();JSONObject getfileCompares();
}

serviceimpl

import com.alibaba.fastjson.JSONObject;import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;@Service
public class FileComparesServiceImpl implements FileComparesService {private static final Logger logger = Logger.getLogger(FileComparesServiceImpl.class);public static String syncCurrentName1 = null; // 进度条namepublic static String percentage1; // 进度条百分比public static Integer percentagesum1 = null; // 文件总数public static int[] countfile;//当前文件个数public static final ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>();//全局静态变量private List listoneNot1 = new ArrayList<Fc>(); //存放数据一缺失的数据private List listoneNot2 = new ArrayList<Fc>(); //存放数据二缺失的数据private List listoneNot3 = new ArrayList<Fc>(); //存放数据二缺失的数据public static boolean flag;private Boolean[] scanStop = new Boolean[1]; // 检测停止标识@Overridepublic void fileComparesimple(String firstpath, String secondpath) {long startTime = System.currentTimeMillis();// 读取服务器cpu核数int cpuCount = Util.getCPUnum();cpuCount = cpuCount > 10 ? 10 : 5;
//        int cpuCount = 4;countfile = new int[]{0};//        String dirName1 = "C:\\Users\\taiyu\\Desktop\\file2\\10w";String dirName1 = firstpath;File root1 = new File(dirName1);String dirName2 = secondpath;File root2 = new File(dirName2);listoneNot1 = new ArrayList<Fc>();listoneNot2 = new ArrayList<Fc>();listoneNot3 = new ArrayList<Fc>();scanStop[0] = true;List list = new ArrayList();list.add(dirName1);list.add(dirName2);logger.info("分配线程开始...");CountDownLatch latchs = new CountDownLatch(cpuCount + 1);ExecutorService exec = Executors.newCachedThreadPool();// 读取文件线程final ReadFile2 trFile1 = new ReadFile2(latchs, null, list,dirName1, dirName2, scanStop);logger.info("读取文件线程启动...");exec.execute(new Thread() {@Overridepublic void run() {trFile1.readFile();}});for (int i = 0; i < cpuCount; i++) {final CompareThreadUtil thDao = new CompareThreadUtil(latchs, null, list, listoneNot1,listoneNot2, listoneNot3, root1,root2, dirName1, dirName2, trFile1, scanStop);System.out.println("检测线程" + i + " 启动...");final int currentID = i;exec.execute(new Thread() {@Overridepublic void run() {thDao.addFileLevelAfter(currentID, percentagesum1, countfile);}});}try {exec.shutdown();latchs.await();} catch (InterruptedException e) {e.printStackTrace();}//结束时间long endTime1 = System.currentTimeMillis();//打印System.out.println("对比运行时间:" + (double) (endTime1 - startTime) / 1000 + "s");//打印数据1缺失数据if (listoneNot1.size() > 0) {logger.info("数据1删除的文件如下");for (int i = 0; i < listoneNot1.size(); i++) {logger.info(((Fc) listoneNot1.get(0)).getPath());}} else {logger.info("数据1无删除的文件...");}//打印数据2缺失数据if (listoneNot2.size() > 0) {logger.info("数据2删除的文件如下");for (int i = 0; i < listoneNot2.size(); i++) {logger.info(((Fc) listoneNot2.get(i)).getPath());}} else {logger.info("数据2无删除文件");}//打印数据3缺失数据if (listoneNot3.size() > 0) {logger.info("两数据源之间发生修改的文件如下");for (int i = 0; i < listoneNot3.size(); i++) {logger.info(((Fc) listoneNot3.get(i)).getPath());}} else {logger.info("两数据源之间无发生修改的文件");}//结束时间long endTime = System.currentTimeMillis();//打印System.out.println("程序运行时间:" + (double) (endTime - startTime) / 1000 + "s");JSONObject jsonObject = new JSONObject();jsonObject.put("数据源1发生删除的文件", listoneNot1);jsonObject.put("数据源2发生删除的文件", listoneNot2);jsonObject.put("两数据源对比发生修改的文件", listoneNot3);flag = true;jsonObject.put("flag", flag);}@Overridepublic Integer initPercentage(String firstpath, String secondpath) {flag = false;percentagesum1 = 0;percentage1 = "";syncCurrentName1 = "";readFileInfo(new File(firstpath));readFileInfo(new File(secondpath));return percentagesum1;}@Overridepublic JSONObject fileComparesimplePercentage() {JSONObject jsonObject = new JSONObject();jsonObject.put("百分比", percentage1);jsonObject.put("当前进行到的文件", syncCurrentName1);jsonObject.put("flag", flag);//为true时可以取结果return jsonObject;}@Overridepublic JSONObject getfileCompares() {JSONObject jsonObject = new JSONObject();jsonObject.put("数据源1发生删除的文件", listoneNot1);jsonObject.put("数据源2发生删除的文件", listoneNot2);jsonObject.put("两数据源对比发生修改的文件", listoneNot3);return jsonObject;}private void readFileInfo(File root) {if (root.exists()) {if (root.isDirectory()) {File[] files = root.listFiles();if (files != null) {for (int i = 0; i < files.length; i++) {if (files[i].isFile()) {percentagesum1++;} else if (files[i].isDirectory()) {readFileInfo(files[i]);}files[i] = null;}}files = null;} else if (root.isFile()) {percentagesum1++;}}}
}

helloWorldApplication

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;@SpringBootApplication( exclude= DataSourceAutoConfiguration.class)
public class helloWorldApplication {public static void main(String[] args) {SpringApplication.run(helloWorldApplication.class, args);}
}

文件对比8,单线程读,多线程对比,对比进度条,对比结果导出excel文件,已验收相关推荐

  1. h5页面如何预览excel文件_如何使用JavaScript实现前端导入和导出excel文件?(H5编辑器实战复盘)...

    前言 最近笔者终于把H5-Dooring的后台管理系统初步搭建完成, 有了初步的数据采集和数据分析能力, 接下来我们就复盘一下其中涉及的几个知识点,并一一阐述其在Dooring H5可视化编辑器中的解 ...

  2. 如何使用JavaScript实现前端导入和导出excel文件(H5编辑器实战复盘)

    前言 最近笔者终于把H5-Dooring的后台管理系统初步搭建完成, 有了初步的数据采集和数据分析能力, 接下来我们就复盘一下其中涉及的几个知识点,并一一阐述其在Dooring H5可视化编辑器中的解 ...

  3. EasyExcel入门:导出Excel文件

    在开发过程中,我们经常需要导出Excel文件,一开始我使用的是Apache POI,通过创建XSSFWorkbook对象来导出Excel数据,但实际使用时发现需要占用较大的内存空间且导出时间较长,于是 ...

  4. java导入、导出Excel文件

    一.介绍 当前B/S模式已成为应用开发的主流,而在企业办公系统中,常常有客户这样子要求:你要把我们的报表直接用Excel打开(电信系统.银行系统).或者是:我们已经习惯用Excel打印.这样在我们实际 ...

  5. Java:使用POI导出Excel文件后打开文件提示因为文件格式或文件扩展名无效而无法打开

    使用POI导出Excel文件后打开文件提示因为文件格式或文件扩展名无效而无法打开 问题 方案 问题 在SpringBoot项目中,使用POI导出查询结果至Excel文件中,成功导出后打开Excel文件 ...

  6. 关于Excel操作编写的一个软件设计构思案例[连载] --如何把处理好后的数据导出Excel文件中(含背景\字体颜色设置)

    导出数据到Excel文件中二种方法四种形式:其一是创建新的Excel文件实例写入数据:其二是打开已有Excel文档对其执行更新或插入数据:保存文档方法有:直接保存(2种).另存.间接保存.接下来分别介 ...

  7. 使用POI批量导出Excel文件(SSM)

    文章目录 前言 如何使用POI批量导出Excel文件(SSM) 一.什么是POI? 模块 二.使用步骤 1.引入依赖 2.mapper层代码 包括Mapper接口.Mapper SQL代码 Mappe ...

  8. EasyExcel 导入导出Excel文件

    文章目录 写在前面 1.maven依赖 2.导入Excel文件 2.1.读取表格文件 2.2.如果有多个sheet表格 2.3.监听器封装(也可不封装) 2.4.读取数据格式化(实体类中添加注解) 3 ...

  9. vue2.0通过Axios导出excel文件(解决乱码问题)

    vue2.0通过Axios导出excel文件(解决乱码问题) 参考文章: (1)vue2.0通过Axios导出excel文件(解决乱码问题) (2)https://www.cnblogs.com/ad ...

最新文章

  1. Sicily 7974. Integer Lists 解题报告
  2. 【PAT乙级】1069 微博转发抽奖 (20 分)
  3. 初步认识Volatile-JMM
  4. 深入mysql语言_MySQL对数据操作的一些深入语法
  5. 小程序开发提示没有npm路径_百度小程序三个框架的各自的特点
  6. mysql哨兵机制_Redis 哨兵机制以及底层原理深入解析,这次终于搞清楚了
  7. linux学习134 unit6
  8. usaco-3.3-shopping-passed
  9. 大学生计算机应用论文,大学生计算机应用论文(共1178字).doc
  10. 万稞pw80线切割编程软件_常用 CNC编程软件
  11. CreateThread与_beginthread 内存泄漏的本质
  12. TypeScript初始化
  13. STM32G030 低功耗
  14. Java后端实现Excel导出,及添加Excel文件标题样式
  15. C++ - 求一个正整数的二进制表示中1的个数
  16. 智能算法和人工智能算法,人工智能算法概念股票
  17. python中@用法
  18. 史上最详细的讲解,第一次如何上传本地代码到github
  19. Python告诉你:8.3分口碑炸裂!潘粤明版《鬼吹灯》到底好看在哪儿?
  20. 对话孟岩:通证经济背后的陷阱及方法论

热门文章

  1. 大学毕业,应该去大公司?还是小公司?
  2. 题库管理系统(部分代码)
  3. 自动驾驶性能和车辆动力学评估软件,助你一整个拿捏自动驾驶
  4. Yahoo 邮箱模拟登陆
  5. git 提交代码时 remote: error:
  6. 基于java小区物业管理系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署
  7. 要成为一名合格的团队管理者你需要看这十本团队管理书籍
  8. Snakes and Ladders(简单高斯消元)
  9. 基于FPGA的小数计算学习
  10. 你早该这么玩Excel 读书笔记