Pu Zhibing
2025-04-11 9b98866bfad109458761d143d02915f1fe7cf65e
ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordUtil.java
@@ -5,7 +5,6 @@
import freemarker.template.Template;
import freemarker.template.TemplateException;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.mock.web.MockMultipartFile;
@@ -60,112 +59,6 @@
    private TencentCosUtil tencentCosUtil;
    @Resource
    private PdfUtils pdfUtils;
    public String generate(String basePackagePath, String templateFileName, Object templateParam, String fileName, String saveDirectory) {
        try {
            // 创建 Freemarker 的 Configuration 对象,设置默认的不兼容改进选项
            Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
            configuration.setDefaultEncoding("utf-8");
            // 设置模板加载器,加载模板文件
            configuration.setTemplateLoader(new ClassTemplateLoader(getClass(), basePackagePath));
            Template t = configuration.getTemplate(templateFileName, "utf-8");
            // 使用 URLEncoder 对文件名进行编码,以防止中文文件名在不同浏览器和操作系统下出现乱码问题
//            String encodedFileName = URLEncoder.encode(fileName + "_" + System.currentTimeMillis(), "utf-8");
            String encodedFileName =fileName ;
            // 定义保存文件的路径
            File saveDir = new File(saveDirectory);
            if (!saveDir.exists()) {
                saveDir.mkdirs();
            }
            // 定义文件名
            String filePath = saveDir.getAbsolutePath() + File.separator + encodedFileName + ".doc";
            // 创建 Writer 对象,用于将生成的文档写到文件中,缓存区大小设为 10KB
            Writer out = new BufferedWriter(new FileWriter(filePath), 10240);
            // 将模型数据与模板结合生成 Word 文档,写入到 Writer 对象中
            t.process(templateParam, out);
            out.close();
            File file = new File(filePath);
            // 检查文件是否存在
            if (!file.exists()) {
                throw new FileNotFoundException("文件不存在: " + filePath);
            }
            // 读取文件内容
            byte[] fileContent = new byte[(int) file.length()];
            try (FileInputStream fis = new FileInputStream(file)) {
                fis.read(fileContent);
            }
            MultipartFile mockMultipartFile = new MockMultipartFile(encodedFileName+".doc", fileContent);
            String s = tencentCosUtil.upLoadFile(mockMultipartFile,"/wordGenerate");
            return s;
        } catch (IOException | TemplateException e) {
            log.error("生成Word文档异常,异常原因:{}", e.getMessage(), e);
            throw new RuntimeException("生成Word文档异常,异常原因:" + e.getMessage());
        }
    }
    public String generatePdf(String basePackagePath, String templateFileName, Map<String,Object> templateParam, String fileName, String saveDirectory,String url) {
        try {
            fillTemplate(basePackagePath+templateFileName, saveDirectory+fileName+".docx", templateParam,url);
            // 创建 Freemarker 的 Configuration 对象,设置默认的不兼容改进选项
//            Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
//            configuration.setDefaultEncoding("utf-8");
//            // 设置模板加载器,加载模板文件
//            configuration.setTemplateLoader(new ClassTemplateLoader(getClass(), basePackagePath));
//            Template t = configuration.getTemplate(templateFileName, "utf-8");
//
//            // 使用 URLEncoder 对文件名进行编码,以防止中文文件名在不同浏览器和操作系统下出现乱码问题
////            String encodedFileName = URLEncoder.encode(fileName + "_" + System.currentTimeMillis(), "utf-8");
//            String encodedFileName =fileName ;
//
//            // 定义保存文件的路径
//            File saveDir = new File(saveDirectory);
//            if (!saveDir.exists()) {
//                saveDir.mkdirs();
//            }
//
//            // 定义文件名
//            String filePath = saveDir.getAbsolutePath() + File.separator + encodedFileName + ".doc";
//
//            // 创建 Writer 对象,用于将生成的文档写到文件中,缓存区大小设为 10KB
//            Writer out = new BufferedWriter(new FileWriter(filePath), 10240);
//
//            // 将模型数据与模板结合生成 Word 文档,写入到 Writer 对象中
//            t.process(templateParam, out);
//            out.close();
            String filePath = saveDirectory + File.separator + fileName + ".docx";
            File file = new File(filePath);
            // 检查文件是否存在
            if (!file.exists()) {
                throw new FileNotFoundException("文件不存在: " + filePath);
            }
            // 读取文件内容
            byte[] fileContent = new byte[(int) file.length()];
            try (FileInputStream fis = new FileInputStream(file)) {
                fis.read(fileContent);
            }
            String test = pdfUtils.test(fileName + ".docx");
//            MultipartFile mockMultipartFile = new MockMultipartFile(encodedFileName+".doc", fileContent);
//            String s = ObsUploadUtil.obsUpload(mockMultipartFile);
            return test;
        } catch (IOException e) {
            log.error("生成pdf异常,异常原因:{}", e.getMessage(), e);
            throw new RuntimeException("生成pdf异常,异常原因:" + e.getMessage());
        }
    }
    public static void fillTemplate(String templatePath, String outputPath,Map<String, Object> dataMap,String url) {
        try (FileInputStream fis = new FileInputStream(templatePath)) {
            // 设置默认编码为UTF-8
@@ -173,7 +66,6 @@
            XWPFDocument document = new XWPFDocument(fis);
            XWPFParagraph pic = document.createParagraph();
            XWPFRun picRun = pic.createRun();
            Base64.Decoder decoder = Base64.getDecoder();
            byte[] imageByte = decoder.decode(url);
            InputStream stream = new ByteArrayInputStream(imageByte);
@@ -189,12 +81,6 @@
                    out.write(buffer, 0, length);
                }
            }
            dataMap.put("${picture}", picRun.addPicture(
                    new FileInputStream(tempFile), XWPFDocument.PICTURE_TYPE_JPEG,
                    "/usr/local/project/file/sign.jpg",
                    Units.toEMU(60),
                    Units.toEMU(30)
            ));
            // 处理段落
            for (XWPFParagraph paragraph : document.getParagraphs()) {
                replaceParagraph(paragraph, dataMap);
@@ -210,7 +96,22 @@
                    }
                }
            }
            //处理图片
            for (XWPFParagraph paragraph : document.getParagraphs()) {
                List<XWPFRun> runs = paragraph.getRuns();
                for (XWPFRun run : runs) {
                    String text = run.getText(0);
                    if (text != null && text.contains("picture")) {
                        run.setText("", 0); // 清除占位符文本
                        run.addPicture(
                                new FileInputStream(tempFile), XWPFDocument.PICTURE_TYPE_JPEG,
                                "/usr/local/project/file/sign.jpg",
                                Units.toEMU(60),
                                Units.toEMU(30)); // 插入图片
                    }
                }
            }
            // 使用UTF-8编码保存文件
            try (FileOutputStream fos = new FileOutputStream(outputPath)) {
                document.write(fos);
@@ -312,20 +213,6 @@
        return result.toString();
    }
    private static class ReplacementInfo {
        int startRun;
        int endRun;
        String originalText;
        String replacementText;
        ReplacementInfo(int startRun, int endRun, String originalText, String replacementText) {
            this.startRun = startRun;
            this.endRun = endRun;
            this.originalText = originalText;
            this.replacementText = replacementText;
        }
    }
    private static void replaceRunRange(XWPFParagraph paragraph, ReplacementInfo info) {
        List<XWPFRun> runs = paragraph.getRuns();
@@ -346,6 +233,125 @@
        style.applyStyle(newRun);
    }
    public String generate(String basePackagePath, String templateFileName, Object templateParam, String fileName, String saveDirectory) {
        try {
            // 创建 Freemarker 的 Configuration 对象,设置默认的不兼容改进选项
            Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
            configuration.setDefaultEncoding("utf-8");
            // 设置模板加载器,加载模板文件
            configuration.setTemplateLoader(new ClassTemplateLoader(getClass(), basePackagePath));
            Template t = configuration.getTemplate(templateFileName, "utf-8");
            // 使用 URLEncoder 对文件名进行编码,以防止中文文件名在不同浏览器和操作系统下出现乱码问题
//            String encodedFileName = URLEncoder.encode(fileName + "_" + System.currentTimeMillis(), "utf-8");
            String encodedFileName =fileName ;
            // 定义保存文件的路径
            File saveDir = new File(saveDirectory);
            if (!saveDir.exists()) {
                saveDir.mkdirs();
            }
            // 定义文件名
            String filePath = saveDir.getAbsolutePath() + File.separator + encodedFileName + ".doc";
            // 创建 Writer 对象,用于将生成的文档写到文件中,缓存区大小设为 10KB
            Writer out = new BufferedWriter(new FileWriter(filePath), 10240);
            // 将模型数据与模板结合生成 Word 文档,写入到 Writer 对象中
            t.process(templateParam, out);
            out.close();
            File file = new File(filePath);
            // 检查文件是否存在
            if (!file.exists()) {
                throw new FileNotFoundException("文件不存在: " + filePath);
            }
            // 读取文件内容
            byte[] fileContent = new byte[(int) file.length()];
            try (FileInputStream fis = new FileInputStream(file)) {
                fis.read(fileContent);
            }
            MultipartFile mockMultipartFile = new MockMultipartFile(encodedFileName+".doc", fileContent);
            String s = tencentCosUtil.upLoadFile(mockMultipartFile,"/wordGenerate");
            return s;
        } catch (IOException | TemplateException e) {
            log.error("生成Word文档异常,异常原因:{}", e.getMessage(), e);
            throw new RuntimeException("生成Word文档异常,异常原因:" + e.getMessage());
        }
    }
    public String generatePdf(String basePackagePath, String templateFileName, Map<String,Object> templateParam, String fileName, String saveDirectory,String url) {
        try {
            fillTemplate(basePackagePath+templateFileName, saveDirectory+fileName+".docx", templateParam,url);
            // 创建 Freemarker 的 Configuration 对象,设置默认的不兼容改进选项
//            Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
//            configuration.setDefaultEncoding("utf-8");
//            // 设置模板加载器,加载模板文件
//            configuration.setTemplateLoader(new ClassTemplateLoader(getClass(), basePackagePath));
//            Template t = configuration.getTemplate(templateFileName, "utf-8");
//
//            // 使用 URLEncoder 对文件名进行编码,以防止中文文件名在不同浏览器和操作系统下出现乱码问题
////            String encodedFileName = URLEncoder.encode(fileName + "_" + System.currentTimeMillis(), "utf-8");
//            String encodedFileName =fileName ;
//
//            // 定义保存文件的路径
//            File saveDir = new File(saveDirectory);
//            if (!saveDir.exists()) {
//                saveDir.mkdirs();
//            }
//
//            // 定义文件名
//            String filePath = saveDir.getAbsolutePath() + File.separator + encodedFileName + ".doc";
//
//            // 创建 Writer 对象,用于将生成的文档写到文件中,缓存区大小设为 10KB
//            Writer out = new BufferedWriter(new FileWriter(filePath), 10240);
//
//            // 将模型数据与模板结合生成 Word 文档,写入到 Writer 对象中
//            t.process(templateParam, out);
//            out.close();
            String filePath = saveDirectory + File.separator + fileName + ".docx";
            File file = new File(filePath);
            // 检查文件是否存在
            if (!file.exists()) {
                throw new FileNotFoundException("文件不存在: " + filePath);
            }
            // 读取文件内容
            byte[] fileContent = new byte[(int) file.length()];
            try (FileInputStream fis = new FileInputStream(file)) {
                fis.read(fileContent);
            }
            String test = pdfUtils.test(fileName + ".docx");
//            MultipartFile mockMultipartFile = new MockMultipartFile(encodedFileName+".doc", fileContent);
//            String s = ObsUploadUtil.obsUpload(mockMultipartFile);
            return test;
        } catch (IOException e) {
            log.error("生成pdf异常,异常原因:{}", e.getMessage(), e);
            throw new RuntimeException("生成pdf异常,异常原因:" + e.getMessage());
        }
    }
    private static class ReplacementInfo {
        int startRun;
        int endRun;
        String originalText;
        String replacementText;
        ReplacementInfo(int startRun, int endRun, String originalText, String replacementText) {
            this.startRun = startRun;
            this.endRun = endRun;
            this.originalText = originalText;
            this.replacementText = replacementText;
        }
    }
    // 用于保存和恢复运行样式的辅助类
    private static class RunStyle {
        String fontFamily;