我有一个简单的 Java 程序,它接受一个 .jrxml 文件,编译它,然后填充它。报告的数据以 XML 文件的形式提供。填充完成后,数据将导出到 PDF 。
// Parse input document
Document document = JRXmlUtils.parse(new File(xmlFile));
// Set it as the data source in the parameters
parameters.put(JRXPathQueryExecuterFactory.PARAMETER_XML_DATA_DOCUMENT, document);
// Create and set the virtualizer
JRFileVirtualizer virtualizer = new JRFileVirtualizer(2, "/tmp");
virtualizer.setReadOnly(true);
parameters.put(JRParameter.REPORT_VIRTUALIZER, virtualizer);
// Fill the report
String jasperFile = designFile.replaceAll(".jrxml",".jasper");
print = JasperFillManager.fillReport(jasperFile, parameters);
// Export the report to PDF
ArrayList<JasperPrint> jasperPrints = new ArrayList<JasperPrint>();
jasperPrints.add(print);
JRPdfExporter exp = new JRPdfExporter();
exp.setParameter (JRExporterParameter.JASPER_PRINT_LIST, jasperPrints);
exp.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, outFileName );
exp.exportReport();
我的困惑是关于出口
上面的填充行适用于小型报告,但是一旦我的 XML 源文件接近1/2 MB,它将旋转超过一天,无论设置文件虚拟化器(我这样做)。
我看到另一个名为fillReportToSteam
的方法。我的困惑是,fillReport
,我必须做一个额外的步骤来导出到PDF。 fillReportToStream
写入什么类型的流,以及如何指定? fillReportToStream
会写入PDF文件吗?
我找不到任何例子。我希望我可以利用这个流,这样我就可以测量进度并让这些 PDF 在正常的时间内完成。
答案 0 :(得分:2)
调用fillReportToStream
仍会生成JasperPrint
对象,但它会将其直接写入输出流,而不是将其传回给您。 JasperFillManager
无法以任何其他格式输出报告,因此无法跳过导出步骤。要生成PDF,您仍然需要使用JRPdfExporter
并从输出流将其写入的任何位置读取填充的报告。
我认为这里的问题是你的文件虚拟器。你提到“它会旋转超过一天,无论设置文件虚拟器”,但虚拟器实际上会使进程更长。这是一个基本的时间/内存权衡,以避免内存不足错误,但会使填充更慢。在我看到的基准测试中,添加文件虚拟化器四倍填充时间!
如果您确实需要虚拟器,请尝试增加您传递的maxSize参数。 2似乎非常低。您也可以尝试切换到JRSwapFileVirtualizer
,因为我听说他们有更好的表现。
答案 1 :(得分:1)
使用样本:
public class ExporterReport {
private byte[] report = null;
private String reportName = "myreport";
protected Collection<? extends Object> getData() {
//TODO: return your collection
}
protected String getReportPath() {
return "/report/myreport.jasper";
}
public final void buildReportXLS() {
Map<String, Object> params = new HashMap<String, Object>();
try {
params.put("text", "sametext");
String reportUrl = getReportPath();
Collection<? extends Object> collection = getData();
if (!collection.isEmpty()) {
URL urlJasper = FacesContext.getCurrentInstance().getExternalContext().getResource(reportUrl);
JRDataSource data = new JRBeanCollectionDataSource(collection);
JasperPrint jasperPrint = null;
try {
jasperPrint = JasperFillManager.fillReport(urlJasper.getPath(), params, data);
if (jasperPrint != null) {
/**
* 1- export to PDF sample
*/
//JasperExportManager.exportReportToPdfFile(jasperPrint, "C://sample_report.pdf");
/**
* 2- export to HTML Sample
*/
//JasperExportManager.exportReportToHtmlFile(jasperPrint,"C://sample_report.html");
/**
* 3- export to Excel sheet
*/
JRXlsExporter exporter = new JRXlsExporter();
ByteArrayOutputStream xlsReport = new ByteArrayOutputStream();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, xlsReport);
exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE);
exporter.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE, Boolean.TRUE);
exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);
exporter.setParameter(JRXlsExporterParameter.IS_IGNORE_GRAPHICS,Boolean.FALSE);
exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS,Boolean.TRUE);
exporter.exportReport();
xlsReport.flush();
xlsReport.close();
this.setReport(xlsReport.toByteArray());
}
} catch (JRException e) {
e.printStackTrace();
}
if (log.isInfoEnabled()) {
log.info("Report build successful", reportName);
}
} catch (Exception e) {
log.error("has a error {0} in {1}: {2} [{3}]", e, reportName, new Date(), e.getMessage(), "information");
}
}
public void downloadReportXLS() {
if (this.getReport() != null) {
this.downloadFile(this.getReport(), reportName + ".xls");
}
}
private void downloadFile(byte[] bytes, String fileName) {
try {
String contentType = null;
FacesContext facesContext = FacesContext.getCurrentInstance();
HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
if (fileName.lastIndexOf('.') != -1) {
contentType = URLConnection.getFileNameMap().getContentTypeFor(fileName);
}
if (StringUtil.isStringEmpty(contentType)) {
contentType = "application/octet-stream";
}
response.setContentType(contentType);
response.addHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
response.addHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
response.setContentLength(bytes.length);
ServletOutputStream os = response.getOutputStream();
os.write(bytes);
os.flush();
os.close();
facesContext.responseComplete();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在你的xhtml中你可以把它放在:
<h:commandButton value="Export to sheet" actionListener="#{exportReport.buildReportXLS()}" action="#{exportReport.downloadReportXLS()}" />