gaoluyang
21 小时以前 abd339106ed3a6465293edccd33e5f87bd43bdde
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package com.ruoyi.manage.util;
 
import com.aspose.words.Document;
import com.aspose.words.DocumentBuilder;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import com.ruoyi.framework.exception.ErrorException;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.core.io.ClassPathResource;
 
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
 
/**
 * 体系文件附件预览工具:把附件统一以 PDF 流输出给前端预览/盖章。
 * PDF 原样输出;Word、图片用 Aspose.Words 在线转 PDF;Excel/PPT 等无法转 PDF 的格式给出明确提示。
 */
public final class DocumentPreviewUtils {
 
    private static final String[] WORD_EXT = {".doc", ".docx", ".rtf", ".txt", ".wps"};
    private static final String[] IMAGE_EXT = {".png", ".jpg", ".jpeg", ".bmp", ".gif"};
 
    private DocumentPreviewUtils() {
    }
 
    public static void writeAsPdf(File file, HttpServletResponse response) throws Exception {
        if (file == null || !file.exists()) {
            throw new ErrorException("附件不存在或已被删除");
        }
        String name = file.getName().toLowerCase();
        if (name.endsWith(".pdf")) {
            prepare(response, file.getName(), file.length());
            try (InputStream in = new FileInputStream(file);
                 OutputStream os = response.getOutputStream()) {
                in.transferTo(os);
                os.flush();
            }
            return;
        }
 
        Document doc;
        if (endsWithAny(name, WORD_EXT)) {
            applyLicense();
            doc = new Document(file.getPath());
        } else if (endsWithAny(name, IMAGE_EXT)) {
            applyLicense();
            doc = new Document();
            new DocumentBuilder(doc).insertImage(file.getPath());
        } else {
            throw new ErrorException("该文件格式不支持在线盖章预览,请上传 PDF 或 Word 文件");
        }
 
        // 先转换到内存,转换失败时响应头还没提交,前端才能收到错误信息
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        doc.save(buffer, SaveFormat.PDF);
        byte[] bytes = buffer.toByteArray();
        prepare(response, file.getName() + ".pdf", bytes.length);
        try (OutputStream os = response.getOutputStream()) {
            os.write(bytes);
            os.flush();
        }
    }
 
    private static void prepare(HttpServletResponse response, String fileName, long length) {
        response.setContentType("application/pdf");
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-disposition", "inline;filename=" + fileName);
        response.setContentLength((int) length);
    }
 
    private static boolean endsWithAny(String name, String[] suffixes) {
        for (String suffix : suffixes) {
            if (name.endsWith(suffix)) {
                return true;
            }
        }
        return false;
    }
 
    private static void applyLicense() throws Exception {
        // 凭证,否则转换后带水印
        try (InputStream is = new ClassPathResource("lib/license.xml").getInputStream()) {
            License license = new License();
            license.setLicense(is);
        }
    }
}