package com.product.file.util; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.Font; import com.lowagie.text.Paragraph; import com.lowagie.text.pdf.BaseFont; import com.lowagie.text.pdf.PdfWriter; import java.io.*; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * java 文件转pdf * * @author cheng * @Date 2021年10月19日 */ public class JavaFileToPdfUtil { /** * window 自带的字体文件 */ private static final String FONT = "C:\\Windows\\Fonts\\msyh.ttf"; /** * 保存pdf的文件夹 (需要提前创建好) */ private static final String savePdfFolder = "E:\\Desktop\\pdf\\"; /** * 转换文件的目录 获取该目录下所有的 .java 类型的文件 */ private static final String convertingFileDirectories = "D:\\product\\产品运营\\产品著作权\\java"; /** * 是否开启线程转换 */ private static final boolean EnableThread = true; /** * 每个线程处理java文件数量 */ private static final int ThreadCount = 10; /** * 是否创建目录 * * @param path * @return */ public static boolean isexitsPath(String path) throws InterruptedException { String[] paths = path.split("\\\\"); StringBuffer fullPath = new StringBuffer(); for (int i = 0; i < paths.length; i++) { fullPath.append(paths[i]).append("\\\\"); File file = new File(fullPath.toString()); if (!file.exists()) { file.mkdir(); // System.out.println("创建目录为:" + fullPath.toString()); } } File file = new File(fullPath.toString()); if (!file.exists()) { return true; } else { return false; } } public static void text2pdf() throws DocumentException, IOException, InterruptedException { File savePdfFolder = new File(JavaFileToPdfUtil.savePdfFolder); if (!savePdfFolder.exists()) { System.out.println("错误:保存转换后PDF目录不存在请创建," + savePdfFolder); return; } File convertingFileDirectories = new File(JavaFileToPdfUtil.convertingFileDirectories); if (!convertingFileDirectories.exists()) { System.out.println("错误:需要转换的文件目录不存在," + convertingFileDirectories); return; } List file = getFile(null); for (int i = 0; i < file.size(); i++) { String parent1 = convertingFileDirectories.getParent(); String savePath = file.get(i).getParent().replace(parent1, savePdfFolder.getPath()); isexitsPath(savePath); } ThreadPoolTool threadPoolTool = new ThreadPoolTool<>(EnableThread ? ThreadCount : file.size(), file); threadPoolTool.setCallBack((files) -> { try { new FileOut().run(files); } catch (Exception e) { e.printStackTrace(); } }); threadPoolTool.excute(false); System.out.println("转换完成,共" + file.size() + "个java文件"); } static class FileOut { public void run(List files) throws Exception { File savePdfFolder = new File(JavaFileToPdfUtil.savePdfFolder); File convertingFileDirectories = new File(JavaFileToPdfUtil.convertingFileDirectories); for (int i = 0; i < files.size(); i++) { Document document = new Document(); String parent1 = convertingFileDirectories.getParent(); System.out.println("正在处理:" + files.get(i).getPath()); String savePath = files.get(i).getParent().replace(parent1, savePdfFolder.getPath()); String fileName = files.get(i).getName(); OutputStream os = new FileOutputStream(new File(savePath + "\\" + fileName.substring(0, fileName.lastIndexOf(".")) + ".pdf")); PdfWriter.getInstance(document, os); document.open(); //方法一:使用Windows系统字体(TrueType) BaseFont baseFont = BaseFont.createFont(FONT, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); Font font = new Font(baseFont); InputStreamReader isr = new InputStreamReader(new FileInputStream(files.get(i)), "UTF-8"); BufferedReader bufferedReader = new BufferedReader(isr); String str = ""; while ((str = bufferedReader.readLine()) != null) { document.add(new Paragraph(str, font)); } document.close(); os.flush(); os.close(); isr.close(); bufferedReader.close(); } } } // 给定目录的绝对路径,获取该目录下的所有文件(子目录的文件也可递归得到) private static List getFile(String path) { // File对象 可以是文件或者目录 File file = new File(path == null ? convertingFileDirectories : path); File[] array = file.listFiles(); List result = new ArrayList<>(); for (int i = 0; i < array.length; i++) { if (array[i].isFile()) { File file1 = array[i]; String name = file1.getName(); String file_type = name.substring(name.lastIndexOf(".") + 1); if (file_type.equalsIgnoreCase("java")) { result.add(array[i]); } } else if (array[i].isDirectory()) { result.addAll(getFile(array[i].getPath())); } } return result; } public static void main(String[] args) throws IOException, DocumentException, InterruptedException { text2pdf(); // System.out.println(new File(convertingFileDirectories).getParent()); } static class ThreadPoolTool { //单个线程处理的数据量 private int singleCount; //处理的总数据量 private int listSize; //开启的线程数 private int runSize; //操作的数据集 private List list; //计数器 private CountDownLatch begin, end; //线程池 private ExecutorService executorService; //回调 private CallBack callBack; public void setCallBack(CallBack callBack) { this.callBack = callBack; } public ThreadPoolTool(int singleCount, List list) { this.singleCount = singleCount; this.list = list; if (list != null) { this.listSize = list.size(); this.runSize = (this.listSize / this.singleCount) + 1; if (singleCount == 1) { this.runSize -= 1; } } } public void excute(boolean async) throws InterruptedException { executorService = Executors.newFixedThreadPool(runSize); begin = new CountDownLatch(1); end = new CountDownLatch(runSize); //创建线程 int startIndex = 0; int endIndex = 0; List newList = null; for (int i = 0; i < runSize; i++) { //计算每个线程对应的数据 if (i < (runSize - 1)) { startIndex = i * singleCount; endIndex = (i + 1) * singleCount; newList = list.subList(startIndex, endIndex); } else { startIndex = i * singleCount; endIndex = listSize; newList = list.subList(startIndex, endIndex); } //创建线程类处理数据 MyThread myThread = new MyThread(newList, begin, end) { @Override public void method(List list) { callBack.method(list); } }; //执行线程 if (!async) { executorService.submit(myThread); } else { executorService.execute(myThread); } } //计数器减一 begin.countDown(); end.await(); //关闭线程池 executorService.shutdown(); } //抽象线程类 public abstract class MyThread implements Runnable { private List list; private CountDownLatch begin, end; public MyThread(List list, CountDownLatch begin, CountDownLatch end) { this.list = list; this.begin = begin; this.end = end; } @Override public void run() { try { //执行程序 method(list); begin.await(); } catch (InterruptedException e) { e.printStackTrace(); throw new RuntimeException(e.getMessage()); } finally { //计数器减一 end.countDown(); } } public abstract void method(List list); } //回调接口定义 public interface CallBack { public void method(List list); } } }