我将Java 11 Corretto+Spring Boot与Apache POI结合使用,但在AWS Lambda上使用时遇到了问题.如果我以"普通"API运行,效果很好,但在AWS lambda中运行servless时失败.

try (ByteArrayOutputStream out = new ByteArrayOutputStream(); SXSSFWorkbook workbook = new SXSSFWorkbook(1000)) {
    SXSSFSheet sheet = workbook.createSheet("test"); //error here!!
    } ...

原因:java.lang.错误:可能的致命错误:没有物理字体

我试图修复字体,但不知道如何继续

@PostConstruct
public void loadFonts() {
    URL configURL = getClass().getClassLoader().getResource("fontconfig.properties");
    String path = configURL != null ? configURL.getPath() : null;
    Properties props = System.getProperties();
    LOGGER.info("Loading font config file: {}", path);
    props.put("sun.awt.fontconfig", path);

    String[] fonts;
    try {
        GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
    } catch (Throwable ex) {
        LOGGER.warn("Reloading Fonts");
    }
    try {
        fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();

        for (String font : fonts) {
            LOGGER.info("Available Font: {}", font);
        }
    } catch (Throwable ex) {
        LOGGER.error("Could not load Fonts");
    }
}

配置文件:

version=1
sequence.allfonts=default

在AWS Lambda上运行时,它会向日志(log)输出一些字体,因此我不明白为什么会出现此错误:

2022-05-31 16:00:14  INFO  Starting Lambda Container Handler
2022-05-31 16:00:18  INFO  Loading font config file: /var/task/fontconfig.properties
2022-05-31 16:00:18  INFO  Available Font: Dialog
2022-05-31 16:00:18  INFO  Available Font: DialogInput
2022-05-31 16:00:18  INFO  Available Font: Monospaced
2022-05-31 16:00:18  INFO  Available Font: SansSerif
2022-05-31 16:00:18  INFO  Available Font: Serif

知道如何添加物理字体吗?为什么POI不能使用输出到日志(log)中的可用字体?

EDIT:

`props.setProperty("java.awt.headless", "true");`

推荐答案

Fonts bundling

知道如何添加物理字体吗

自Java 11起,Oracle stopped bundling fontsOracle JDK产品.

OpenJDK项目没有Bundle 字体,至少在最新版本中没有.

来自Amazon的Corretto JDK产品基于OpenJDK代码库.根据你的报告,显然他们没有Bundle 字体.

您必须 Select :

  • 依赖主机操作系统提供的字体.
  • 在Java应用程序中Bundle 字体.仔细研究许可条款.有些字体允许这样的Bundle ,有些不允许.有些需要付费,有些不允许.有些需要确认,有些不允许.
  • 从包含字体的供应商处获取JDK.

我知道至少有一家这样的供应商:Azul Systems将字体与Azul Platform Core种商业产品Bundle 在一起.

我不知道还有其他这样的供应商.许多供应商提供JDK二进制文件和安装程序.这些供应商包括Adoptium、SAP、BellSoft、Microsoft、Azul Systems、Amazon、Oracle、Red Hat/IBM、Pivotal等.

Physical fonts versus logical fonts

为什么POI不能使用输出到日志(log)的可用字体

日志(log)中列出的字体是logical种,而不是physical种.Font类的Javadoc中清楚地记录了这种区别.

要使用逻辑字体名称,您必须有一些支持的物理字体.如果应用程序、JDK或主机操作系统中没有字体,则逻辑字体无法工作.

Fonts for AWS Lambda

关于在AWS Lambda中提供字体,这两个页面可能会有所帮助.(感谢jarmod for the links.)

基本思想是在包中创建一个/fonts文件夹.在中包含fonts.conf文件,其中包含XML配置元素.将Bundle 的字体文件放在该配置文件旁边.

Java相关问答推荐

如何在Spring Security中设置CustomLogin路径?

Intellij显示项目语言级别最高为12,尽管有java版本17 SDK

如何打印本系列的第n项y=-(1)-(1+2)+(1+2+3)+(1+2+3+4)-(1+2+3+4+5)...Java中的(1+2+3+4...+n)

我不能再在Android Studio Hedgehog上用Java语言创建新项目了吗?

Bean定义不是从Spring ApplationConext.xml文件加载的

由于 list 中的权限错误,Android未生成

将响应转换为带值的键

WebSockets和Spring Boot安全性出现错误401

使用存储在字符串变量中的路径目录打开.pdf文件

Domino Designer 14中的保存代理添加了重影库

如何在Cosmos DB(Java SDK)中增加默认响应大小

来自外部模块的方面(对于Java+Gradle项目)不起作用

如何在Jooq中获取临时表列引用?

寻找Thread.sky()方法的清晰度

从字节数组切换到JakartaMail org.springframework.mail.javamail.JavaMailSender InputStreamResource

如何在Selenium上继续使用最新的WebDriver版本

如何使用stream.allMatch()为空流返回false?

如何正确使用java.time类?

Spring Boot Security-每个端点都被403禁止,Spring记录一个BasicErrorController#错误(HttpServlet请求)

java.exe如何执行java源代码?