From ac4bf3bccb266666a60fd0addb73bce125d43758 Mon Sep 17 00:00:00 2001
From: xuhy <3313886187@qq.com>
Date: 星期四, 06 三月 2025 19:15:26 +0800
Subject: [PATCH] bug修改

---
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/PdfUtils.java |  218 +++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 183 insertions(+), 35 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 9c274d7..172bfd6 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
@@ -4,6 +4,7 @@
 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;
@@ -11,7 +12,11 @@
 
 import java.io.*;
 import java.net.URL;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
 @Slf4j
@@ -22,7 +27,6 @@
     /**
      * word 转 pdf
      *
-     * @param url
      */
 //    public  String wordToPdf(String url,String filePath, String fileName) {
 //        try {
@@ -62,48 +66,192 @@
 //        return null;
 //    }
 
-    public String wordToPdf(String url, String filePath, String fileName) {
+    public String wordToPdf(String filePath, String fileName) {
         try {
-            DocumentType documentType = DocumentType.DOC;
-            if (url.contains(".docx")) {
-                documentType = DocumentType.DOCX;
-            } else if (url.contains(".doc")) {
-                documentType = DocumentType.DOC;
-            } else if (url.contains(".xlsx")) {
-                documentType = DocumentType.XLSX;
-            } else if (url.contains(".xls")) {
-                documentType = DocumentType.XLS;
-            }
+            // 1. 首先确保输入文件是UTF-8编码
+            String inputFile = filePath + fileName;
+            String outputDir = filePath + "/pdf";
+            String outputFileName = fileName.substring(0, fileName.lastIndexOf(".")) + ".pdf";
 
-            // Ensure the URL has a protocol part
-            if (!url.startsWith("file://") && !url.startsWith("http://") && !url.startsWith("https://")) {
-                url = "file://" + url;
-            }
+            // 2. 创建临时文件用于转换
+            String tempDocx = createTempFileWithEncoding(inputFile);
 
-            // 使用LibreOffice进行转换
-            ProcessBuilder pb = new ProcessBuilder(
-                    "soffice",
-                    "--headless",
-                    "--convert-to", "pdf",
-                    "--outdir", new File(filePath+ "/pdf"+fileName.substring(0, fileName.lastIndexOf(".")) + ".pdf").getParent(),
-                    filePath+fileName
-            );
+            // 3. 使用更详细的LibreOffice转换参数
+            List<String> command = new ArrayList<>();
+            command.add("/usr/bin/soffice");
+            command.add("--headless");
+            command.add("--convert-to");
+            command.add("pdf:writer_pdf_Export:PDFExport{'EmbedStandardFonts':true}");
+            command.add("--outdir");
+            command.add(outputDir);
+            command.add(tempDocx);
+
+            ProcessBuilder pb = new ProcessBuilder(command);
+
+            // 4. 设置更完整的环境变量
+            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");
+            env.put("PYTHONIOENCODING", "utf8");
+            env.put("JAVA_TOOL_OPTIONS", "-Dfile.encoding=UTF-8");
+
+            // 5. 执行转换
             Process process = pb.start();
 
-            // 等待转换完成
-            int exitCode = process.waitFor();
-            if (exitCode == 0) {
-                System.out.println("PDF转换成功!");
-            } else {
-                System.out.println("PDF转换失败!");
+            // 6. 读取输出
+            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");
+                }
             }
-            return "";
+
+            // 7. 等待进程完成
+            int exitCode = process.waitFor();
+
+            // 8. 清理临时文件
+            new File(tempDocx).delete();
+
+            if (exitCode == 0) {
+                return outputDir + "/" + outputFileName;
+            } else {
+                throw new RuntimeException("转换失败: " + output.toString());
+            }
+
         } catch (Exception e) {
-            e.printStackTrace();
-            throw new RuntimeException("Failed to generate PDF: " + e.getMessage(), e);
+            throw new RuntimeException("PDF转换失败: " + e.getMessage(), e);
+        }
+    }
+    private static String createTempFileWithEncoding(String inputFile) {
+        try {
+            // 1. 读取原始文档
+            XWPFDocument doc = new XWPFDocument(new FileInputStream(inputFile));
+
+            // 2. 修改文档字体和编码
+            for (XWPFParagraph paragraph : doc.getParagraphs()) {
+                for (XWPFRun run : paragraph.getRuns()) {
+                    // 设置中文字体
+                    run.setFontFamily("WenQuanYi Zen Hei");
+                    run.setFontFamily("WenQuanYi Zen Hei", XWPFRun.FontCharRange.eastAsia);
+
+                    // 确保文本是UTF-8编码
+                    String text = run.getText(0);
+                    if (text != null) {
+                        text = new String(text.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
+                        run.setText(text, 0);
+                    }
+                }
+            }
+
+            // 3. 处理表格中的文本
+            for (XWPFTable table : doc.getTables()) {
+                for (XWPFTableRow row : table.getRows()) {
+                    for (XWPFTableCell cell : row.getTableCells()) {
+                        for (XWPFParagraph paragraph : cell.getParagraphs()) {
+                            for (XWPFRun run : paragraph.getRuns()) {
+                                run.setFontFamily("WenQuanYi Zen Hei");
+                                run.setFontFamily("WenQuanYi Zen Hei", XWPFRun.FontCharRange.eastAsia);
+
+                                String text = run.getText(0);
+                                if (text != null) {
+                                    text = new String(text.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
+                                    run.setText(text, 0);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            // 4. 保存为临时文件
+            String tempFile = inputFile + ".temp.docx";
+            try (FileOutputStream out = new FileOutputStream(tempFile)) {
+                doc.write(out);
+            }
+
+            return tempFile;
+
+        } catch (Exception e) {
+            throw new RuntimeException("处理文档编码失败: " + e.getMessage(), e);
         }
     }
 
+    // 在转换之前执行的环境检查
+    private static void preConversionCheck() {
+        try {
+            // 1. 检查并安装必要的字体
+            installRequiredFonts();
+
+            // 2. 验证LibreOffice安装
+            verifyLibreOfficeInstallation();
+
+            // 3. 设置字体配置
+            setupFontConfig();
+
+        } catch (Exception e) {
+            throw new RuntimeException("环境检查失败: " + e.getMessage(), e);
+        }
+    }
+
+    private static void installRequiredFonts() {
+        try {
+            ProcessBuilder pb = new ProcessBuilder(
+                    "sudo", "apt-get", "install", "-y",
+                    "fonts-wqy-zenhei",
+                    "fonts-wqy-microhei",
+                    "fonts-arphic-ukai",
+                    "fonts-arphic-uming"
+            );
+            pb.inheritIO();
+            Process p = pb.start();
+            p.waitFor();
+        } catch (Exception e) {
+            System.err.println("警告: 安装字体失败 - " + e.getMessage());
+        }
+    }
+
+    private static void verifyLibreOfficeInstallation() {
+        try {
+            Process p = Runtime.getRuntime().exec("soffice --version");
+            try (BufferedReader reader = new BufferedReader(
+                    new InputStreamReader(p.getInputStream()))) {
+                String version = reader.readLine();
+                if (version == null || !version.contains("LibreOffice")) {
+                    throw new RuntimeException("LibreOffice未正确安装");
+                }
+            }
+        } catch (Exception e) {
+            throw new RuntimeException("LibreOffice检查失败: " + e.getMessage());
+        }
+    }
+
+    private static void setupFontConfig() {
+        try {
+            String fontConfig =
+                    "<?xml version='1.0'?>\n" +
+                            "<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>\n" +
+                            "<fontconfig>\n" +
+                            "  <match target=\"pattern\">\n" +
+                            "    <test name=\"family\"><string>SimSun</string></test>\n" +
+                            "    <edit name=\"family\" mode=\"assign\" binding=\"same\">\n" +
+                            "      <string>WenQuanYi Zen Hei</string>\n" +
+                            "    </edit>\n" +
+                            "  </match>\n" +
+                            "</fontconfig>";
+
+            String userHome = System.getProperty("user.home");
+            File fontConfigFile = new File(userHome + "/.fonts.conf");
+
+            try (FileWriter writer = new FileWriter(fontConfigFile)) {
+                writer.write(fontConfig);
+            }
+        } catch (Exception e) {
+            System.err.println("警告: 设置字体配置失败 - " + e.getMessage());
+        }
+    }
 
     public static MultipartFile convertToMultipartFile(ByteArrayOutputStream baos, String fileName) throws IOException {
         // 创建一个临时文件
@@ -251,12 +399,12 @@
     }
 
     public String test(String fileName){
-        String url = "file:///usr/local/project/file/"+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(url, filePath, fileName);
+        String s = wordToPdf(filePath, fileName);
         System.err.println(s);
 
         return s;

--
Gitblit v1.7.1