我有一个Java批处理作业,可以打印100万页(1页)PDF文档。 此批处理作业将在每5天后运行。
通过批量作业打印100万(1页)PDF文档,哪种方法更好?
在本PDF中,大部分文本/段落对所有客户都是相同的,只有少数信息是从数据库中动态选取的(客户ID /名称/截止日期/到期日/金额)
我们已尝试过以下
1)贾斯珀报告
2)iText
但是上面两种方法没有提供更好的性能,因为每个文档的静态文本/段落始终是在运行时创建的。
所以我正在考虑像
这样的方法将有一个模板,其中包含动态值的占位符(客户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());
答案 0 :(得分:2)
哇。每5天有100万个PDF文件。
即使从头到尾生成PDF文件只需0.5秒(磁盘上已完成的文件) - 按顺序生成此数量的PDF需要5天时间。
我认为任何在亚秒级时间内生成文件的方法都很好(Jasper报告当然可以为您提供这种级别的性能)。
我认为你需要考虑如何优化整个过程:你肯定会使用多线程甚至几个物理服务器来生成任意数量的文件。时间(至少一夜)。
答案 1 :(得分: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();
}
}
答案 2 :(得分:0)
正如一些海报所提到的,100万个PDF文件意味着你将不得不维持每秒超过2个文件的速度。这可以从纯文档生成方面实现,但您需要记住,运行查询和编译数据的系统上的负载也将承受合理的负载。您还没有说过任何关于PDF的内容 - 单页PDF比40页PDF更容易生成...
我已经看到iText和Docmosis每秒可以实现数十个文档,所以Jasper和其他技术也可能。我提到了Docmosis,因为它与你提到的技术一致(填充模板加载到内存中)。请注意我为生产Docmosis的公司工作。
如果您还没有,则需要考虑硬件/软件架构,并使用您尝试的任何技术进行试用,以确保您能够获得所需的性能。据推测,峰值负荷可能略高于平均负荷。
祝你好运。