0

我有一个 Java 批处理作业,可以打印 100 万(1 页)PDF 文档。此批处理作业将每 5 天运行一次。

对于通过批处理作业打印 100 万(1 页)PDF 文档,哪种方法更好?

在此 PDF 中,所有客户的大部分文本/段落都是相同的,只有少数信息是从数据库中动态选择的(客户 ID/姓名/到期日/到期日/金额)

我们尝试了以下

1) 贾斯珀报告

2) 文本

但是以上两种方法并没有提供更好的性能,因为每个文档的静态文本/段落总是在运行时创建。

所以我正在考虑一些方法,比如

将有一个模板,其中包含动态值的占位符(客户 ID/姓名/到期日/到期日/金额)。

将会有一个像 Open Office 这样的通信服务器,它会有这个模板。

通过我们部署在 Web 服务器上的 Java 应用程序将从数据库中获取数据集并传递到该通信服务器,其中模板已经打开到内存中,并且仅从数据集中动态占位符值将被更改,模板将像“另存为”命令一样保存。

上述方法是否可以实现,如果可以,哪个 API / 通信服务器更好?

这是 Jasper 报告代码供参考

InputStream is = getClass().getResourceAsStream("/jasperreports/reports/"+reportName+".jasper" );    
JasperPrint print = JasperFillManager.fillReport(is, parameters, dataSource);    
pdf = File.createTempFile("report.pdf", "");
JasperExportManager.exportReportToPdfFile(print, pdf.getPath());
4

3 回答 3

2

哇。每 5 天 100 万个 PDF 文件。

即使从头到尾生成一个 PDF 文件(磁盘上的一个完成文件)只需要 0.5 秒 - 您也需要 5 天的时间才能依次生成这么多 PDF。

我认为在亚秒级时间内生成文件的任何方法都很好(Jasper 报告当然可以为您提供这种级别的性能)。

我认为您需要考虑如何优化整个过程:您肯定将不得不使用多线程,甚至可能需要多个物理服务器来在任何合理的时间内生成这么多文件(在至少过夜)。

于 2012-08-27T07:00:06.867 回答
1

我将使用 PDF 表单(这应该是“快速”):

public final class Batch
{
    private static final String FORM = "pdf-form.pdf"

    public static void main(final String[] args) {
        final PdfPrinter printer = new PdfPrinter(FORM);
        final List<Customer> customers = readCustomers();

        for(final Customer customer : customers) {
            try {
                printer.fillAndCreate("pdf-" + customer.getId(), customer);
            } catch (IOException e) {
                // handle exception
            } catch (DocumentException e) {
                // handle exception
            }
        }

        printer.close();
    }

    private @Nonnull List<Customers> readCustomers() {
        // implements me
    }

    private Batch() {
        // nothing
    }
}

public class PdfPrinter implements Closable
{
    private final PdfReader reader;

    public PdfPrinter(@Nonnull final String src) {
        reader = new PdfReader(src); // <= this reads the form pdf
    }

    @Override 
    public void close() {
        reader.close();
    }

    public void fillAndCreate(@Nonnull final String dest, @Nonnull final Customer customer) throws IOException, DocumentException {
        final PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest)); // dest = output
        final AcroFields form = stamper.getAcroFields();
        form.setField("customerId", customer.getId());
        form.setField("name", customer.getName());
        // ...
        stamper.close();
    }
}

另见:http: //itextpdf.com/examples/iia.php ?id=164

于 2012-08-27T06:46:53.573 回答
0

正如几张海报所提到的,100 万个 PDF 文件意味着您将不得不维持每秒超过 2 个文档的速度。这可以从纯文档生成方面实现,但您需要记住,运行查询和编译数据的系统上的负载也将承受合理的负载。你也没有说任何关于 PDF 的事情 - 一页 PDF 比 40 页 PDF 更容易生成......

我已经看到 iText 和 Docmosis 每秒可以处理数十个文档,因此 Jasper 和其他技术可能也可以。我提到 Docmosis 是因为它按照您提到的技术(填充加载到内存中的模板)工作。请注意,我为制作 Docmosis 的公司工作。

如果您还没有,您将需要考虑硬件/软件架构,并使用您尝试的任何技术进行试验,以确保您能够获得所需的性能。据推测,峰值负载可能略高于平均负载。

祝你好运。

于 2012-09-17T09:16:45.090 回答