You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PdfConverter首次转换缓慢原因及Spring Boot优雅初始化方案咨询

Word转PDF首次转换速度过慢问题排查与优化咨询

我使用PdfConverter实现Word转PDF功能时,发现首次转换速度极慢,后续转换则明显加快。Spring Boot应用中该接口响应时间大致为12s→300ms→300ms。推测PdfConverter存在缓存机制,但未找到相关逻辑,耗时差异主要出现在PdfConverter#doConvert→XWPFDocumentVisitor#visitor() visitBodyElements环节。

复现代码

PdfOptions options = PdfOptions.create();  
XWPFDocument xwpfDocument;  
String resourceLocation = "classpath:template/cadreTemplate-new.docx";  
File template = ResourceUtils.getFile(resourceLocation);  
try (FileInputStream inputStream = new FileInputStream(template)) {  
xwpfDocument = new XWPFDocument(inputStream);  
}  
PdfConverter.getInstance().convert(xwpfDocument, new ByteArrayOutputStream(), options);

Maven依赖

<dependency>  
    <groupId>fr.opensagres.xdocreport</groupId>  
    <artifactId>fr.opensagres.poi.xwpf.converter.pdf-gae</artifactId>  
    <version>2.0.3</version>  
</dependency>

咨询问题

  1. 不同的Word模板是否需要每次都初始化,还是只需初始化一次?
  2. 如何在Spring中以优雅的方式初始化PdfConverter,以缩短首次请求的响应时间?

我已尝试多种方式排查响应时间差异问题。


问题解答

关于模板初始化的问题

  • 不同的Word模板需要各自初始化:每个模板的结构、样式、内容都存在差异,XWPFDocument是绑定具体模板的实例,无法跨模板复用。但如果是同一模板的多次转换,可缓存XWPFDocument实例(需注意线程安全,若模板内容无动态修改需求,可全局缓存)。

Spring中优化首次响应时间的方案

1. 启动时预热初始化

利用Spring的ApplicationRunner或CommandLineRunner,在项目启动阶段执行一次轻量转换操作,触发PdfConverter内部的类加载、资源初始化等耗时逻辑:

@Component
public class PdfConverterWarmer implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 使用轻量测试模板完成首次初始化
        String testTemplatePath = "classpath:template/test-empty.docx";
        File testTemplate = ResourceUtils.getFile(testTemplatePath);
        try (FileInputStream inputStream = new FileInputStream(testTemplate)) {
            XWPFDocument doc = new XWPFDocument(inputStream);
            PdfConverter.getInstance().convert(doc, new ByteArrayOutputStream(), PdfOptions.create());
        }
    }
}

2. 复用PdfConverter单例实例

PdfConverter.getInstance()本身已是单例实现,确保整个应用中复用该实例即可,无需重复创建。

3. 固定模板缓存优化

对于频繁使用的固定模板,提前加载并缓存XWPFDocument实例(需保证模板文件不会被动态修改):

@Component
public class TemplateCache {

    private final Map<String, XWPFDocument> templateCache = new ConcurrentHashMap<>();

    @PostConstruct
    public void initCommonTemplates() throws Exception {
        // 预加载常用模板
        loadTemplate("cadreTemplate", "classpath:template/cadreTemplate-new.docx");
    }

    private void loadTemplate(String key, String path) throws Exception {
        File template = ResourceUtils.getFile(path);
        try (FileInputStream inputStream = new FileInputStream(template)) {
            templateCache.put(key, new XWPFDocument(inputStream));
        }
    }

    public XWPFDocument getTemplate(String key) {
        return templateCache.get(key);
    }
}

使用时直接从缓存获取模板实例,避免重复读取文件和初始化XWPFDocument的开销。


内容的提问来源于stack exchange,提问作者Smile

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 20:35:02