spire.pdf 在 docker 容器中

spire.pdf in a docker container

我创建了一个处理 pdf 并将其转换为 pdfa3 并将文档转换为 facturX 的应用程序。我使用 Springboot 开发了我的应用程序,它运行良好。现在我正在尝试 docker 化我的应用程序。我遇到了数据库连接问题,现在我遇到了以下问题

facturx_1  | 2022-03-21 16:20:55.565 ERROR 1 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is class com.spire.ms.System.Exception: No 'Arial' font found!
...
facturx_1  | com.spire.pdf.conversion.PdfStandardsConverter.toPdfA3B(Unknown Source)
facturx_1  | fr.company.app.shared.Utils.loadPdfA3(Utils.java:88)
facturx_1  | fr.company.app.service.impl.FacturXServiceImpl.createFacturX(FacturXServiceImpl.java:75)
facturx_1  | fr.company.app.ui.controller.FacturXController.createFacturXOutoutStream(FacturXController.java:54)
...
facturx_1  | java.base/java.lang.Thread.run(Unknown Source)] with root cause
facturx_1  |
facturx_1  | com.spire.ms.System.Exception: No 'Arial' font found!
facturx_1  |    at com.spire.pdf.packages.sprZOa.spr  (Unknown Source) ~[spire.pdf.free-5.1.0.jar!/:5.1.0]
...
facturx_1  |    at com.spire.pdf.conversion.PdfStandardsConverter.toPdfA3B(Unknown Source) ~[spire.pdf.free-5.1.0.jar!/:5.1.0]
facturx_1  |    at fr.company.app.shared.Utils.loadPdfA3(Utils.java:88) ~[classes!/:0.0.1-SNAPSHOT]
facturx_1  |    at fr.company.app.service.impl.FacturXServiceImpl.createFacturX(FacturXServiceImpl.java:75) ~[classes!/:0.0.1-SNAPSHOT]
facturx_1  |    at fr.company.app.ui.controller.FacturXController.createFacturXOutoutStream(FacturXController.java:54) ~[classes!/:0.0.1-SNAPSHOT]

我的代码如下:

public static PDDocument loadPdfA3(String pdfData) {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

    byte[] decoded = Base64.getDecoder().decode(pdfData);
    InputStream inputStream = new ByteArrayInputStream(decoded);

    PdfStandardsConverter converter = new PdfStandardsConverter(inputStream);
    converter.toPdfA3B(outputStream);

    byte[] pdfBytes = outputStream.toByteArray();
    InputStream pdfInputStream = new ByteArrayInputStream(pdfBytes);

    try {
        return PDDocument.load(pdfInputStream);
    } catch (IOException e) {
        throw new AppServiceException(e.getLocalizedMessage());
    }
}

returns异常的行如下converter.toPdfA3B(outputStream)

我执行以下 docker 文件:

# Build stage
FROM maven:3.8.4-openjdk-11 AS build
WORKDIR /app
COPY . /app
RUN mvn clean package -DskipTests

# Package and Run stage
FROM openjdk:11.0.14.1-jre
COPY --from=build app/target/facturx-ws.jar /usr/local/lib/facturx-ws.jar
EXPOSE 8092

ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=docker", "/usr/local/lib/facturx-ws.jar"]

这也是我的docker撰写:

version: "3"
services:
  facturx:
    container_name: facturx
    image: facturx
    restart: always
    build:
      context: ./
      dockerfile: Dockerfile
    ports:
      - "8081:8080"
    environment:
      MYSQL_HOST: mysqldb
      MYSQL_USER: root
      MYSQL_PASSWORD: root
      MYSQL_PORT: 3306
    #    depends_on:
    #      - mysqldb
    networks:
      - appnetwork

  mysqldb:
    container_name: mysqldb
    image: mysql:8.0.28-oracle
    command: ['mysqld','--character-set-server=utf8','--default-authentication-plugin=mysql_native_password']
    volumes:
      - dbstore:/var/lib/mysql
    ports:
      - "3309:3306"
    environment:
      MYSQL_DATABASE: facturx
      MYSQL_ROOT_PASSWORD: root
    restart: unless-stopped
    networks:
      - appnetwork

volumes:
  dbstore: {}

networks:
  appnetwork:
    driver: bridge

异常显示:未找到 'Arial' 字体。请注意,在 non-windows 系统上使用 spire.pdf 转换 pdf 文件时,您需要确保安装了文件中所有使用的字体,否则您的应用程序可能会抛出此类异常。这是 spire 论坛上的 similar post

我更改了我的 Dockerfile :

# Build stage
FROM maven:3.8.4-openjdk-11 AS build

WORKDIR /app
COPY ../../facturx-ws/. /app
COPY ../../facturx-ws/src/main/resources/xsd /app/xsd
RUN mvn clean package -DskipTests

# Package and Run stage
FROM openjdk:11.0.14.1-jre
COPY --from=build app/target/facturx-ws.jar /usr/local/lib/facturx-ws.jar
COPY --from=build app/xsd /usr/local/lib/xsd
#COPY app/facturx-ws/src/main/resources/xsd /usr/local/lib/xsd
RUN echo "ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true" | debconf-set-selections
RUN sed -i'.bak' 's/$/ contrib/' /etc/apt/sources.list
RUN apt-get update; apt-get install -y ttf-mscorefonts-installer fontconfig
RUN fc-cache -f -v
#EXPOSE 8092
ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=docker", "/usr/local/lib/facturx-ws.jar"]

我通过 运行 ttf-mscorefonts-installer

安装了 windows 字体

感谢 davidvera 的回答。

下面用 e-iceblue:spire.pdf.free:4.4.1e-iceblue:spire.pdf.free:5.1.0

进行了测试

在我们的案例中,解决方案是针对我们遇到的问题:

  1. Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.spire.doc.packages...
  2. com.spire.ms.System.Exception: No 'Arial' font found!
  3. "Neutral cultures cannot be used in formatting and parsing and therefore cannot be set as the thread's current culture"
change impact
Used JDK instead of JRE fixed classloading issues (your issue outlined above did not appear)
Used debian instead of alpine (as base) unknown
Installed msttcorefonts no missing Arial issue
Ensure to set locale via Locale.setDefault(Locale.ROOT); Get rid of issue the cultural issue ;)

知道这不再是轻量级 docker 图像,但它可以工作,我们使用了以下 Dockerfile。

FROM openjdk:11-jdk
RUN echo "update packages" && apt update && \
  echo "install ms fonts" && \
    sed -i'.bak' 's/$/ contrib/' /etc/apt/sources.list && \
    apt update && \
    apt install -y ttf-mscorefonts-installer fontconfig && \
    fc-cache -f -v

// add other application files