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

如何使用Spring Batch ItemWriter实现PDF文件数据写入?(Spring Boot)

当然有办法实现!Spring Batch本身确实没有提供开箱即用的PDF ItemWriter,但咱们可以自定义一个ItemWriter,搭配成熟的PDF处理库(比如iText或Apache PDFBox)来完成数据写入PDF的需求。下面是具体的实现步骤和示例:

1. 添加PDF处理库依赖

首先得引入PDF操作的依赖,这里以常用的iText 7为例,在你的pom.xml中添加:

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext7-core</artifactId>
    <version>7.2.5</version> <!-- 可以替换为最新稳定版 -->
</dependency>

如果偏好Apache PDFBox,依赖配置是:

<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.32</version>
</dependency>
2. 自定义PDF ItemWriter

接下来写一个实现ItemWriter<T>接口的类,这里假设你要写入的是User类型的业务数据(可以替换成你自己的实体类):

import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;
import java.util.List;

@Component
public class PdfItemWriter implements ItemWriter<User> {

    private final String outputFilePath;
    private PdfDocument pdfDocument;
    private Document document;

    // 通过配置注入PDF输出路径
    public PdfItemWriter(@Value("${pdf.output.path}") String outputFilePath) {
        this.outputFilePath = outputFilePath;
    }

    @Override
    public void write(List<? extends User> items) throws Exception {
        // 第一次写入时初始化PDF文档
        if (pdfDocument == null) {
            PdfWriter writer = new PdfWriter(outputFilePath);
            pdfDocument = new PdfDocument(writer);
            document = new Document(pdfDocument);
            document.add(new Paragraph("用户数据列表").setFontSize(16).setBold());
        }

        // 遍历批次数据,逐行写入PDF
        for (User user : items) {
            String userInfo = String.format("ID: %d, 姓名: %s, 邮箱: %s",
                                           user.getId(), user.getName(), user.getEmail());
            document.add(new Paragraph(userInfo).setMarginTop(5));
        }

        // 每批写入后刷新,避免内存占用过高
        document.flush();
    }

    // 任务结束时关闭文档,确保内容完全写入磁盘
    @PreDestroy
    public void closeDocument() {
        if (document != null) {
            document.close();
        }
        if (pdfDocument != null) {
            pdfDocument.close();
        }
    }
}
3. 配置Spring Batch Job

最后在你的Job配置类中,把这个自定义的ItemWriter整合到Step里:

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.item.ItemReader;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableBatchProcessing
public class BatchConfig {

    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;
    private final ItemReader<User> userItemReader; // 你的数据源Reader
    private final PdfItemWriter pdfItemWriter;

    public BatchConfig(JobBuilderFactory jobBuilderFactory,
                       StepBuilderFactory stepBuilderFactory,
                       ItemReader<User> userItemReader,
                       PdfItemWriter pdfItemWriter) {
        this.jobBuilderFactory = jobBuilderFactory;
        this.stepBuilderFactory = stepBuilderFactory;
        this.userItemReader = userItemReader;
        this.pdfItemWriter = pdfItemWriter;
    }

    @Bean
    public Step exportToPdfStep() {
        return stepBuilderFactory.get("exportToPdfStep")
                .<User, User>chunk(100) // 每批处理100条数据,可根据需求调整
                .reader(userItemReader)
                // 如果需要数据转换,可添加自定义Processor
                // .processor(userItemProcessor)
                .writer(pdfItemWriter)
                .build();
    }

    @Bean
    public Job exportToPdfJob() {
        return jobBuilderFactory.get("exportToPdfJob")
                .start(exportToPdfStep())
                .build();
    }
}
一些实用注意事项
  • 内存优化:处理海量数据时,通过chunk参数控制每批处理的数量,避免一次性加载过多数据到内存;定期调用flush()方法写入磁盘。
  • 样式定制:可以通过iText/PDFBox的API自定义PDF的字体、颜色、表格布局等,让输出格式更贴合业务需求。
  • 异常处理:建议在write方法中添加异常捕获逻辑,避免单条数据错误导致整个任务失败。
  • 资源释放:务必确保任务结束时关闭PDF文档,示例中用@PreDestroy注解实现了自动释放,也可以在Job的监听回调中处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:35:46