You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Apache POI中复用字体?寻求便捷获取已创建字体方案

How to Reuse Workbook Fonts Efficiently in Apache POI?

Great question! This is a common pain point when working with Apache POI's font management—every call to workbook.createFont() creates a new font instance, even if the properties are identical. Not only does this waste resources during runtime, but reusing fonts after restarting your Java app can be a hassle. Let's break down some practical solutions, including an optimized version of your temporary fix, plus more elegant approaches:

1. Runtime Reuse: In-Memory Font Cache

The simplest and most efficient way to avoid duplicate fonts during your program's runtime is to maintain a font cache pool. Use a Map where the key is a unique identifier built from the font's properties (name, size, bold status, color, etc.), and the value is the pre-created Font object. Next time you need a font with the same properties, just pull it from the cache instead of creating a new one.

Here's a quick implementation:

private static final Map<String, Font> FONT_CACHE = new HashMap<>();

public static Font getOrCreateFont(Workbook workbook, String fontName, short fontSize, boolean isBold, short color) {
    // Create a unique key from all font attributes
    String key = String.format("%s-%d-%b-%d", fontName, fontSize, isBold, color);
    
    if (FONT_CACHE.containsKey(key)) {
        return FONT_CACHE.get(key);
    }
    
    Font font = workbook.createFont();
    font.setFontName(fontName);
    font.setFontHeightInPoints(fontSize);
    font.setBold(isBold);
    font.setColor(color);
    
    FONT_CACHE.put(key, font);
    return font;
}

This approach eliminates redundant font creation entirely while your app is running, and it's straightforward to use.

2. Persistent Reuse: Optimized CustomProperty Approach

Your idea of using CustomProperty to store font identifiers is solid—we can refine it to make font lookup after restart much smoother:

  • When creating a font, add a unique CustomProperty tag (like a human-readable ID) to it.
  • When loading an existing workbook later, iterate through fonts and match against this tag instead of checking every property.

Example code:

// Create a font with a unique identifier tag
public static Font createTaggedFont(Workbook workbook, String fontId) {
    Font font = workbook.createFont();
    // Set your desired font properties here (name, size, etc.)
    font.getCustomProperties().addProperty("FONT_UNIQUE_ID", fontId);
    return font;
}

// Retrieve a font by its unique ID from an existing workbook
public static Font getFontByTag(Workbook workbook, String fontId) {
    for (int i = 0; i < workbook.getNumberOfFonts(); i++) {
        Font font = workbook.getFontAt(i);
        CustomProperties props = font.getCustomProperties();
        
        if (props != null && fontId.equals(props.getProperty("FONT_UNIQUE_ID"))) {
            return font;
        }
    }
    return null; // Return null if no matching font found
}

This makes post-restart font lookup far more efficient than checking every font's properties one by one.

3. Advanced: Reuse Fonts from a Template Workbook

If you consistently use a fixed set of fonts across multiple workbooks, create a template workbook with all your pre-configured fonts. Then, either:

  • Create new workbooks based on this template, or
  • Copy the pre-defined fonts from the template to new workbooks.

Here's a rough example of copying fonts:

// Load your pre-configured template workbook
Workbook templateWorkbook = WorkbookFactory.create(new File("font-template.xlsx"));
Workbook newWorkbook = new XSSFWorkbook();

// Copy all fonts from template to new workbook
for (int i = 0; i < templateWorkbook.getNumberOfFonts(); i++) {
    Font templateFont = templateWorkbook.getFontAt(i);
    Font newFont = newWorkbook.createFont();
    
    // Copy all relevant font properties
    newFont.setFontName(templateFont.getFontName());
    newFont.setFontHeightInPoints(templateFont.getFontHeightInPoints());
    newFont.setBold(templateFont.getBold());
    newFont.setColor(templateFont.getColor());
    // Add other properties as needed (italic, underline, etc.)
}

This is perfect for scenarios where your font styles don't change often—set up the template once, and reuse it forever.

Quick Summary

  • Use an in-memory cache for runtime font reuse (fastest, simplest).
  • Opt for the tagged CustomProperty method if you need to reuse fonts across application restarts.
  • Go with a template workbook if you have a fixed set of fonts for all your workbooks.

内容的提问来源于stack exchange,提问作者AFoeee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:42:39