配置Arial字体与CSS后iText运行缓慢问题咨询
Hey there, let's tackle this iText performance issue you're facing after setting up Arial fonts and custom CSS! Based on my experience working with iText for HTML-to-PDF conversions, here are practical, actionable fixes to speed things up:
1. Cache Your Font Instances
The biggest culprit for slowdowns here is often repeated loading and parsing of the Arial font file. iText doesn't automatically cache fonts by default, so every time you render text with Arial, it might re-read the .ttf file from disk.
Fix: Initialize your PdfFont once and reuse it across your entire application:
// Create a static cached font instance (initialize once at app startup) private static PdfFont cachedArialFont; static { try { // Use your actual font path here cachedArialFont = PdfFontFactory.createFont("/path/to/arial.ttf", PdfEncodings.IDENTITY_H, PdfFontFactory.EMBEDDED); } catch (IOException e) { // Handle exception appropriately for your app e.printStackTrace(); } } // Reuse this cached font whenever you need it in your code
If you're applying fonts via CSS, make sure your CSS processor is configured to use this cached font instead of loading it fresh every time.
2. Pre-Parse and Cache Your CSS Stylesheet
Just like fonts, reloading and parsing your CSS file for every conversion adds unnecessary overhead.
Fix: Parse your CSS once and cache the CssStyleSheet instance:
// Cache the stylesheet once at app startup private static CssStyleSheet cachedStylesheet; static { try { cachedStylesheet = new CssStyleSheet(); cachedStylesheet.loadStyleSheet(new FileInputStream("/path/to/your/styles.css")); } catch (IOException e) { e.printStackTrace(); } } // Use the cached stylesheet in your conversion logic ConverterProperties converterProps = new ConverterProperties(); converterProps.setCssStylesheet(cachedStylesheet); // Pass these properties to HtmlConverter HtmlConverter.convertToPdf(yourHtmlContent, new PdfWriter(outputStream), converterProps);
3. Use Font Subsetting
Embedding the entire Arial font file increases both file size and processing time. If you only use a subset of Arial's characters (which is likely for most documents), enable subsetting to reduce the font data iText has to process.
Fix: Enable subsetting when creating your PdfFont:
cachedArialFont = PdfFontFactory.createFont("/path/to/arial.ttf", PdfEncodings.IDENTITY_H, true); // The third parameter `true` tells iText to subset the font
This will only embed the characters actually used in your document, cutting down on processing time and final PDF size.
4. Reuse Conversion Resources
If you're converting multiple HTML documents, avoid creating new ConverterProperties, PdfWriter, or Document instances for each one. Reusing these objects reduces initialization overhead.
Example:
// Configure properties once ConverterProperties converterProps = new ConverterProperties(); converterProps.setCssStylesheet(cachedStylesheet); converterProps.setFontProvider(new DefaultFontProvider() {{ addFont(cachedArialFont.getFontProgram(), PdfEncodings.IDENTITY_H); }}); // Reuse these properties for every conversion for (int i = 0; i < listOfHtmlDocuments.size(); i++) { String htmlDoc = listOfHtmlDocuments.get(i); try (PdfWriter writer = new PdfWriter(new FileOutputStream("output_" + i + ".pdf")); PdfDocument pdfDoc = new PdfDocument(writer); Document doc = new Document(pdfDoc)) { HtmlConverter.convertToElementList(htmlDoc, converterProps).forEach(doc::add); } catch (IOException e) { e.printStackTrace(); } }
5. Verify Resource Paths
Ensure your font and CSS files are loaded from a fast, local location. Avoid using network paths or slow storage (like remote file shares) for these resources. If you're bundling fonts/CSS with your app, load them via the classpath using getResourceAsStream instead of file paths:
// Load font from classpath cachedArialFont = PdfFontFactory.createFont( getClass().getResourceAsStream("/fonts/arial.ttf"), PdfEncodings.IDENTITY_H, true );
If you still see slowdowns after trying these steps, consider profiling your application to identify the exact bottleneck. Tools like Java VisualVM can help you see which methods are taking the most time—whether it's font loading, CSS parsing, or PDF rendering itself.
内容的提问来源于stack exchange,提问作者Alessandra

