Skip to content
CMO & CTO
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

  • Digital Experience
    • Experience Strategy
    • Experience-Driven Commerce
    • Multi-Channel Experience
    • Personalization & Targeting
    • SEO & Performance
    • User Journey & Behavior
  • Marketing Technologies
    • Analytics & Measurement
    • Content Management Systems
    • Customer Data Platforms
    • Digital Asset Management
    • Marketing Automation
    • MarTech Stack & Strategy
    • Technology Buying & ROI
  • Software Engineering
    • Software Engineering
    • Software Architecture
    • General Software
    • Development Practices
    • Productivity & Workflow
    • Code
    • Engineering Management
    • Business of Software
    • Code
    • Digital Transformation
    • Systems Thinking
    • Technical Implementation
  • About
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

Exporting to PDF and XLS: Tuning for Speed

Posted on November 5, 2010 By Luis Fernandez
\n\n\n\n\nI was on pager duty and a user hit Export to Excel right before a big meeting. The spinner felt like a staring contest. Tomcat was fine, CPU was bored, yet the report took ages. I cracked open the logs, watched JasperReports fill pages like a careful scribe, and realized the export was not slow by accident. It was slow by design choices we made months earlier. That night turned into my checklist for speedy PDF and XLS exports without touching business logic. Here is the short list I keep on my desk. \n\n\n\nWhat actually slows your report\n\n\n\nThe heavy cost lives in three places. Data fetch, layout decisions, and exporter settings. Compiling JRXML on every request is a tax you can avoid: compile once, cache the JasperReport, and reuse it. For big lists, set the JDBC fetch size and keep the result stream moving. Subreports are great for reuse, but too many of them can stall the fill step, so cache subreport JasperReports as well and pass data sources instead of making each one hit the database again. When rows are many, use a JRVirtualizer so large pages are swapped to disk and your heap stays calm. \n\n\n\nIf the report is going only to Excel, ignore pagination during fill. JasperPrint can be created as a long flow with no page breaks, which makes the XLS exporter breathe. Layout matters more than we like to admit. Overlapping elements and lots of stretch rules force Jasper to compute bounds for every row. Keep elements aligned to a grid and avoid repeated resizes. Images and big vector shapes make exporters work harder than necessary, so remove what does not help the reader. \n\n\n\nMake PDF faster without losing quality\n\n\n\nPDF speed usually sinks because of fonts and images. If you do not need to embed fonts, do not. Jasper lets you pick the pdfFontName and whether it is embedded. Base 14 fonts like Helvetica render everywhere and keep files small. Turn on compression in the PDF exporter. Resize images before the report sees them and prefer JPEG for photos. Avoid transparent PNG layers since blending is pricey. Lines and rectangles are cheap, but gradients and complex shapes add work. Keep text as text, not as images, so the reader can search and copy. \n\n\n\n
// PDF exporter with compression and cached report\nJasperReport report = getCached("invoice.jasper"); // your cache\nMap<String,Object> params = new HashMap<>();\n\n// Virtualizer for large prints\nJRFileVirtualizer v = new JRFileVirtualizer(50, "/tmp/jasper");\nparams.put(JRParameter.REPORT_VIRTUALIZER, v);\n\nJasperPrint print = JasperFillManager.fillReport(report, params, dataSource);\n\nJRPdfExporter pdf = new JRPdfExporter();\npdf.setParameter(JRExporterParameter.JASPER_PRINT, print);\npdf.setParameter(JRExporterParameter.OUTPUT_STREAM, out);\npdf.setParameter(JRPdfExporterParameter.IS_COMPRESSED, Boolean.TRUE);\npdf.exportReport();\n\nv.cleanup();
\n\n\n\n
\n<textElement>\n  <font pdfFontName="Helvetica" isPdfEmbedded="false"/>\n</textElement>
\n\n\n\nXLS that opens fast and looks right\n\n\n\nExcel readers want data over perfect print layout. The JRXlsExporter is quick when fed a clean grid. Avoid overlapping elements and remove empty vertical gaps. Detect cell types so numbers stay numbers. Turn off white page backgrounds and do not split by page unless you really want separate sheets. Ignore graphics for pure data exports. If the report exists only for Excel, set ignore pagination during fill and let the sheet grow as needed. \n\n\n\n
// Fill without pagination for Excel\nMap<String,Object> xlsParams = new HashMap<>();\nxlsParams.put(JRParameter.IS_IGNORE_PAGINATION, Boolean.TRUE);\n\nJasperPrint xlsPrint = JasperFillManager.fillReport(report, xlsParams, dataSource);\n\n// Fast XLS export settings\nJRXlsExporter xls = new JRXlsExporter();\nxls.setParameter(JRExporterParameter.JASPER_PRINT, xlsPrint);\nxls.setParameter(JRExporterParameter.OUTPUT_STREAM, out);\nxls.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE, Boolean.TRUE);\nxls.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);\nxls.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);\nxls.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE);\nxls.setParameter(JRXlsExporterParameter.IS_IGNORE_GRAPHICS, Boolean.TRUE);\nxls.setParameter(JRXlsExporterParameter.IS_COLLAPSE_ROW_SPAN, Boolean.TRUE);\nxls.exportReport();
\n\n\n\nData and memory tips that pay off right away\n\n\n\nFor large exports, no trick beats moving fewer bytes. Select only the columns you print. Use a forward only result set and set a fetch size that the driver respects. On some databases you get streaming with a special fetch size, so test with your driver. Keep the fill cycle short by using a prepared statement and simple expressions inside the report. Cache compiled reports in a static map at startup and watch cold starts vanish from the logs. \n\n\n\n
// Streaming fetch for large result sets\nStatement st = conn.createStatement(\n    ResultSet.TYPE_FORWARD_ONLY,\n    ResultSet.CONCUR_READ_ONLY\n);\nst.setFetchSize(500); // adjust per driver\nResultSet rs = st.executeQuery(sql);\n\nJRResultSetDataSource ds = new JRResultSetDataSource(rs);\nJasperPrint p = JasperFillManager.fillReport(report, params, ds);
\n\n\n\nJRVirtualizer saves memory by swapping big chunks to disk. Keep the swap path on a fast disk and right size the page count. Release the virtualizer after export. For subreports, pass the parent virtualizer down so every piece shares the same pool. If you run inside a servlet, reuse exporters per request and close streams with a try finally. These small bits do not look fancy, yet they turn red bars on the dashboard into short green blips. \n\n\n\nSummary\n\n\n\nTo speed exporting to PDF and XLS with JasperReports, think in layers. Feed less data. Keep the layout simple. Fill once with smart defaults like ignore pagination for Excel and a virtualizer for big runs. For PDF, avoid font embedding and enable compression. For XLS, detect cell types and skip graphics. Cache compiled reports so the CPU spends time on your users instead of on your templates. The easiest wins come from exporter settings and layout discipline. The rest is patience and a coffee while the first timed run proves you got it right. \n
General Software Software Engineering

Post navigation

Previous post
Next post
  • Digital Experience (94)
    • Experience Strategy (19)
    • Experience-Driven Commerce (5)
    • Multi-Channel Experience (9)
    • Personalization & Targeting (21)
    • SEO & Performance (10)
  • Marketing Technologies (92)
    • Analytics & Measurement (14)
    • Content Management Systems (45)
    • Customer Data Platforms (4)
    • Digital Asset Management (8)
    • Marketing Automation (6)
    • MarTech Stack & Strategy (10)
    • Technology Buying & ROI (3)
  • Software Engineering (310)
    • Business of Software (20)
    • Code (30)
    • Development Practices (52)
    • Digital Transformation (21)
    • Engineering Management (25)
    • General Software (82)
    • Productivity & Workflow (30)
    • Software Architecture (85)
    • Technical Implementation (23)
  • 2025 (12)
  • 2024 (8)
  • 2023 (18)
  • 2022 (13)
  • 2021 (3)
  • 2020 (8)
  • 2019 (8)
  • 2018 (23)
  • 2017 (17)
  • 2016 (40)
  • 2015 (37)
  • 2014 (25)
  • 2013 (28)
  • 2012 (24)
  • 2011 (30)
  • 2010 (42)
  • 2009 (25)
  • 2008 (13)
  • 2007 (33)
  • 2006 (26)

Ab Testing Adobe Adobe Analytics Adobe Target AEM agile-methodologies Analytics architecture-patterns CDP CMS coding-practices content-marketing Content Supply Chain Conversion Optimization Core Web Vitals customer-education Customer Data Platform Customer Experience Customer Journey DAM Data Layer Data Unification documentation DXP Individualization java Martech metrics mobile-development Mobile First Multichannel Omnichannel Personalization product-strategy project-management Responsive Design Search Engine Optimization Segmentation seo spring Targeting Tracking user-experience User Journey web-development

©2025 CMO & CTO | WordPress Theme by SuperbThemes