From efd229f59ecd8aae8e1e9764859824a82bf4b111 Mon Sep 17 00:00:00 2001
From: zhangmei <645025773@qq.com>
Date: 星期三, 19 三月 2025 09:50:11 +0800
Subject: [PATCH] 修改邮件
---
ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/PdfUtils.java | 251 +++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 215 insertions(+), 36 deletions(-)
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/PdfUtils.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/PdfUtils.java
index 2668c3c..ba43f3f 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/PdfUtils.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/PdfUtils.java
@@ -1,21 +1,24 @@
package com.ruoyi.web.controller.tool;
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.http.HttpUtil;
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 javax.annotation.Resource;
import java.io.*;
import java.net.URL;
+import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
-import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
@Slf4j
@Component
@@ -25,47 +28,223 @@
/**
* word 转 pdf
*
- * @param url
*/
- public String wordToPdf(String url,String filePath, String fileName) {
+// 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 {
- 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;
+ // 确保路径正确性
+ String inputFile = new File(filePath, fileName).getAbsolutePath();
+ String outputDir = new File(filePath, "pdf").getAbsolutePath();
+
+ // 创建输出目录
+ new File(outputDir).mkdirs();
+
+ // 使用完整的转换参数
+ List<String> 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<String, String> 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);
}
}
- 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);
+ // 等待进程完成,设置超时
+ if (!process.waitFor(120, TimeUnit.SECONDS)) {
+ process.destroyForcibly();
+ throw new RuntimeException("转换超时");
+ }
- stream.close();
- inputStream.close();
+ 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) {
- e.printStackTrace();
+ throw new RuntimeException("PDF转换失败: " + e.getMessage(), e);
}
- return null;
}
+ 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 =
+ "<?xml version=\"1.0\"?>\n" +
+ "<!DOCTYPE fontconfig SYSTEM \"fonts.dtd\">\n" +
+ "<fontconfig>\n" +
+ " <match target=\"pattern\">\n" +
+ " <test name=\"family\"><string>serif</string></test>\n" +
+ " <edit name=\"family\" mode=\"prepend\">\n" +
+ " <string>WenQuanYi Zen Hei</string>\n" +
+ " </edit>\n" +
+ " </match>\n" +
+ " <match target=\"pattern\">\n" +
+ " <test name=\"family\"><string>sans-serif</string></test>\n" +
+ " <edit name=\"family\" mode=\"prepend\">\n" +
+ " <string>WenQuanYi Zen Hei</string>\n" +
+ " </edit>\n" +
+ " </match>\n" +
+ "</fontconfig>";
+
+ // 写入配置文件
+ 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 {
// 创建一个临时文件
@@ -213,12 +392,12 @@
}
public String test(String fileName){
- String url = "file:///D:\\"+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 = "E:\\";
+ String filePath = "/usr/local/project/file/";
- String s = wordToPdf(url, filePath, fileName);
+ String s = wordToPdf(filePath, fileName);
System.err.println(s);
return s;
--
Gitblit v1.7.1