gpt4 book ai didi

java - Apache POI 获取字体规范

转载 作者:行者123 更新时间:2023-11-30 05:20:04 24 4
gpt4 key购买 nike

我想自动调整 Excel 中的列大小,但又不会消耗太多性能。Apache POI 的内置自动调整大小非常慢(在几个小时后没有完成 100 万行)。为了节省性能,我只想近似单元格宽度,但为此我需要字体规范。

Apache POI 有一个名为 FontDetails 的类,但它不能单独工作。StaticFontMetrics 类似乎是实际加载指标的类,但它不是公开的。但即使将 protected 代码复制到我的工作区并使其可访问,它也无法加载字体规范。

我如何获得这些指标? java.awt.FontMetrics 总是返回准确的结果吗?

编辑:我在尝试获取字体的指标时得到的堆栈跟踪:

Caused by: java.lang.IllegalArgumentException: The supplied FontMetrics doesn't know about the font 'Calibri', so we can't use it. Please add it to your font metrics file (see StaticFontMetrics.getFontDetails
at ourpackagestructure.apachepoi.FontDetails.create(FontDetails.java:106)
at ourpackagestructure.apachepoi.StaticFontMetrics.getFontDetails(StaticFontMetrics.java:94)

最佳答案

Apache poi 使用 AttributedStringTextLayout使特殊字体的文本超出范围。

因此,只要整列采用相同的字体,最好的方法就是首先获取应存储在该列中的最长字符串。然后使用 java.awt.font.TextLayout 获取该字体中该字符串的宽度。然后将其设置为列宽。

请注意,Excel 中的列宽以默认字符宽度的 1/256 为单位设置。因此,除了该字体中的字符串宽度(以像素为单位)之外,您还需要默认字符的宽度来计算 Excel 列宽。

示例:

import java.awt.font.FontRenderContext;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.text.AttributedString;
import java.awt.geom.Rectangle2D;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.SheetUtil;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ApachePoiGetStringWidth {

public static void main(String args[]) throws Exception {

String testString = "Lorem ipsum semit dolor";
String fontName = "Calibri";
short fontSize = 24;
boolean italic = true;
boolean bold = false;

Workbook workbook = new XSSFWorkbook();
Font font = workbook.createFont();
font.setFontHeightInPoints(fontSize);
font.setFontName(fontName);
font.setItalic(italic);
font.setBold(bold);
CellStyle style = workbook.createCellStyle();
style.setFont(font);

AttributedString attributedString = new AttributedString(testString);
attributedString.addAttribute(TextAttribute.FAMILY, font.getFontName(), 0, testString.length());
attributedString.addAttribute(TextAttribute.SIZE, (float)font.getFontHeightInPoints());
if (font.getBold()) attributedString.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, 0, testString.length());
if (font.getItalic()) attributedString.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE, 0, testString.length());

FontRenderContext fontRenderContext = new FontRenderContext(null, true, true);

TextLayout layout = new TextLayout(attributedString.getIterator(), fontRenderContext);
Rectangle2D bounds = layout.getBounds();
double frameWidth = bounds.getX() + bounds.getWidth();

System.out.println(frameWidth);

Sheet sheet = workbook.createSheet();
Row row = sheet.createRow(2);
Cell cell = row.createCell(2);
cell.setCellValue(testString);
cell.setCellStyle(style);

int defaultCharWidth = SheetUtil.getDefaultCharWidth(workbook);
sheet.setColumnWidth(2, (int)Math.round(frameWidth / defaultCharWidth * 256));

try (java.io.FileOutputStream out = new java.io.FileOutputStream("Excel.xlsx")) {
workbook.write(out);
}

workbook.close();

}
}

关于java - Apache POI 获取字体规范,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59713455/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com