package com.ruoyi.web.controller.tool; import com.documents4j.api.DocumentType; import com.documents4j.api.IConverter; import com.documents4j.job.LocalConverter; import lombok.extern.slf4j.Slf4j; import org.apache.poi.xwpf.usermodel.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockMultipartFile; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import java.io.*; import java.net.URL; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; @Slf4j @Component public class PdfUtils { @Autowired private TencentCosUtil tencentCosUtil; /** * word 转 pdf * */ // public String wordToPdf(String url,String filePath, String fileName) { // try { // DocumentType documentType = DocumentType.DOC; // if(url.contains(".docx")){ // documentType = DocumentType.DOCX; // } // if(url.contains(".doc")){ // documentType = DocumentType.DOC; // } // if(url.contains(".xlsx")){ // documentType = DocumentType.XLSX; // }else { // if(url.contains(".xls")){ // documentType = DocumentType.XLS; // } // } // InputStream inputStream = new URL(url).openStream(); // ByteArrayOutputStream stream = new ByteArrayOutputStream(); // IConverter converter = LocalConverter.builder().build(); // converter.convert(inputStream) // .as(documentType) // .to(stream) // .as(DocumentType.PDF).execute(); // // //上传图片 // byte2File(stream.toByteArray(),filePath + "/pdf",fileName.substring(0,fileName.lastIndexOf(".")) + ".pdf"); // MultipartFile multipartFile = convertToMultipartFile(stream,fileName.substring(0,fileName.lastIndexOf(".")) ); // String s = tencentCosUtil.upLoadFile(multipartFile,"/wordToPdf"); // // stream.close(); // inputStream.close(); // return s; // } catch (Exception e) { // e.printStackTrace(); // } // return null; // } public String wordToPdf(String filePath, String fileName) { try { // 确保路径正确性 String inputFile = new File(filePath, fileName).getAbsolutePath(); String outputDir = new File(filePath, "pdf").getAbsolutePath(); // 创建输出目录 new File(outputDir).mkdirs(); // 使用完整的转换参数 List command = Arrays.asList( "/usr/bin/libreoffice", // 使用完整路径 "--headless", "--norestore", "--convert-to", "pdf:writer_pdf_Export:PDFExport{" + "EmbedStandardFonts=1;" + "EmbedFonts=1;" + "EmbedOnlyUsedFonts=0;" + "UseTaggedPDF=1" + "}", "--outdir", outputDir, inputFile ); // 创建进程构建器 ProcessBuilder pb = new ProcessBuilder(command); // 设置环境变量 Map env = pb.environment(); env.put("LC_ALL", "zh_CN.UTF-8"); env.put("LANG", "zh_CN.UTF-8"); env.put("LANGUAGE", "zh_CN.UTF-8"); // 重定向错误流到标准输出 pb.redirectErrorStream(true); // 启动进程 Process process = pb.start(); // 读取输出 StringBuilder output = new StringBuilder(); try (BufferedReader reader = new BufferedReader( new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) { String line; while ((line = reader.readLine()) != null) { output.append(line).append("\n"); System.out.println(line); } } // 等待进程完成,设置超时 if (!process.waitFor(120, TimeUnit.SECONDS)) { process.destroyForcibly(); throw new RuntimeException("转换超时"); } int exitCode = process.exitValue(); if (exitCode != 0) { throw new RuntimeException("转换失败,退出码:" + exitCode + "\n输出:" + output); } // 检查生成的PDF文件 String pdfFileName = fileName.substring(0, fileName.lastIndexOf(".")) + ".pdf"; File pdfFile = new File(outputDir, pdfFileName); if (!pdfFile.exists() || pdfFile.length() == 0) { throw new RuntimeException("PDF文件未生成或为空"); } String absolutePath = pdfFile.getAbsolutePath(); MultipartFile multipartFile = convertFileToMultipartFile(pdfFile); String s = tencentCosUtil.upLoadFile(multipartFile,"/wordToPdf"); return s; } catch (Exception e) { throw new RuntimeException("PDF转换失败: " + e.getMessage(), e); } } public MultipartFile convertFileToMultipartFile(File file) throws IOException { // 读取文件内容到字节数组 byte[] fileContent = Files.readAllBytes(file.toPath()); // 创建 MultipartFile 对象 MultipartFile multipartFile = new MockMultipartFile( file.getName(), // 文件名 file.getName(), // 原始文件名 "application/pdf", // 内容类型,根据实际情况调整 fileContent // 文件内容 ); return multipartFile; } // 在使用前检查和配置环境 public static void setupEnvironment() { try { // 1. 检查LibreOffice安装 checkLibreOffice(); // 2. 检查和安装字体 installFonts(); // 3. 配置字体 configureFonts(); // 4. 验证环境变量 checkEnvironment(); } catch (Exception e) { throw new RuntimeException("环境设置失败: " + e.getMessage(), e); } } private static void checkLibreOffice() throws IOException, InterruptedException { Process process = Runtime.getRuntime().exec("which libreoffice"); if (process.waitFor() != 0) { throw new RuntimeException("LibreOffice未安装"); } } private static void installFonts() throws IOException, InterruptedException { // 创建字体安装脚本 String scriptContent = "#!/bin/bash\n" + "apt-get update\n" + "apt-get install -y fonts-wqy-zenhei fonts-wqy-microhei fonts-arphic-ukai fonts-arphic-uming\n" + "fc-cache -fv\n"; File script = new File("/tmp/install_fonts.sh"); Files.write(script.toPath(), scriptContent.getBytes()); script.setExecutable(true); // 执行脚本 Process process = Runtime.getRuntime().exec("sudo /tmp/install_fonts.sh"); process.waitFor(); // 清理脚本 script.delete(); } private static void configureFonts() throws IOException { // 创建字体配置文件 String fontConfig = "\n" + "\n" + "\n" + " \n" + " serif\n" + " \n" + " WenQuanYi Zen Hei\n" + " \n" + " \n" + " \n" + " sans-serif\n" + " \n" + " WenQuanYi Zen Hei\n" + " \n" + " \n" + ""; // 写入配置文件 File configFile = new File(System.getProperty("user.home") + "/.fonts.conf"); Files.write(configFile.toPath(), fontConfig.getBytes()); } private static void checkEnvironment() { // 检查环境变量 String[] requiredVars = {"LANG", "LC_ALL", "LANGUAGE"}; for (String var : requiredVars) { String value = System.getenv(var); if (value == null || !value.contains("zh_CN")) { System.err.println("警告: " + var + " 环境变量未正确设置"); } } } public static MultipartFile convertToMultipartFile(ByteArrayOutputStream baos, String fileName) throws IOException { // 创建一个临时文件 File tempFile = File.createTempFile(fileName, ".pdf"); // 将ByteArrayOutputStream中的数据写入临时文件 try (FileOutputStream fos = new FileOutputStream(tempFile)) { baos.writeTo(fos); } catch (IOException e) { e.printStackTrace(); } // 创建一个MultipartFile对象 return new MockMultipartFile( fileName + ".pdf", // 参数名称 fileName + ".pdf", // 文件名 "application/pdf", // 内容类型 Files.readAllBytes(tempFile.toPath()) // 文件内容 ); } /** * file转byte */ public static byte[] file2byte(File file){ byte[] buffer = null; try{ FileInputStream fis = new FileInputStream(file); ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] b = new byte[1024]; int n; while ((n = fis.read(b)) != -1) { bos.write(b, 0, n); } fis.close(); bos.close(); buffer = bos.toByteArray(); }catch (FileNotFoundException e){ e.printStackTrace(); } catch (IOException e){ e.printStackTrace(); } return buffer; } /** * byte 转file */ public static File byte2File(byte[] buf, String filePath, String fileName){ BufferedOutputStream bos = null; FileOutputStream fos = null; OutputStreamWriter osw = null; File file = null; try{ File dir = new File(filePath+"/"); if (!dir.exists()){ dir.mkdirs(); } file = new File(filePath +File.separator + fileName); fos = new FileOutputStream(file); bos = new BufferedOutputStream(fos); // osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8); bos.write(buf); }catch (Exception e){ e.printStackTrace(); } finally{ if (bos != null){ try{ bos.close(); }catch (IOException e){ e.printStackTrace(); } } if (fos != null){ try{ fos.close(); }catch (IOException e){ e.printStackTrace(); } } } return file; } /** * multipartFile转File **/ public static File multipartFile2File(MultipartFile multipartFile){ File file = null; if (multipartFile != null){ try { file= File.createTempFile("tmp", null); multipartFile.transferTo(file); System.gc(); file.deleteOnExit(); }catch (Exception e){ e.printStackTrace(); log.warn("multipartFile转File发生异常:"+e); } } return file; } public static void main(String[] args) { // String url = "file:///E:\\qiyeweixin\\WXWork\\1688855207501340\\Cache\\File\\2024-09\\专业技术工作总结.docx"; // String filePath = "E:\\qiyeweixin\\WXWork\\1688855207501340\\Cache\\File\\2024-09"; // String fileName = "专业技术工作总结.docx"; // String s = wordToPdf(url, filePath, fileName); // System.err.println(s); // String url = "file:///F:\\测试动态列表Word.doc"; //// String filePath = "E:\\qiyeweixin\\WXWork\\1688855207501340\\Cache\\File\\2024-09"; //// String fileName = "专业技术工作总结.docx";4 // String filePath = "F:\\"; // // String s = wordToPdf(url, filePath, "测试动态列表Word.doc"); // System.err.println(s); // TODO Auto-generated method stub // HashMap paramMap = new HashMap<>(); // paramMap.put("CorpID", "SCZT006959"); // paramMap.put("Pwd", "123456"); // paramMap.put("Mobile", "19522115070"); // paramMap.put("Cell", ""); // paramMap.put("SendTime", ""); // paramMap.put("Content", java.net.URLEncoder.encode("你好,这是测试短信发送。【职评网】")); // String result3 = HttpUtil.post("http://sdk2.028lk.com/sdk2/BatchSend2.aspx", paramMap); // if (result3 == null) { // result3 = ""; // } // result3 = StrUtil.trim(result3); // log.info("返回结果:" + result3); // // if (result3.matches("^\\d+$") && !result3.equals("0")) { // return; // } } public String test(String fileName){ // String url = "file:///usr/local/project/file/"+fileName; // String filePath = "E:\\qiyeweixin\\WXWork\\1688855207501340\\Cache\\File\\2024-09"; // String fileName = "专业技术工作总结.docx";4 String filePath = "/usr/local/project/file/"; String s = wordToPdf(filePath, fileName); System.err.println(s); return s; } }