OpenHTMLToPDF: вставка пользовательского шрифта в PDF, созданный из HTML

Я создаю PDF-файл из HTML с помощью Jsoup и OpenHTMLToPDF. Мне нужно использовать другой шрифт в моем PDF-файле, чтобы покрыть нелатинские глифы (см. strings-to-a-pdf/5427096#5427096">здесь). Как я могу правильно внедрить свой шрифт?

Упрощенная программа, воспроизводящая проблему:

src/main/resources/test.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Font Test</title>
        <style>
            @font-face {
                font-family: 'source-sans';
                font-style: normal;
                font-weight: 400;
                src: url(fonts/SourceSansPro-Regular.ttf);
            }
        </style>
    </head>
    <body>    
        <p style="font-family: 'source-sans',serif">Latin Script</p>
        <p style="font-family: 'source-sans',serif">Είμαι ελληνικό κείμενο.</p>
    </body>
</html>
  • этот файл должен быть записан в формате PDF
  • В браузере выглядит корректно и использует шрифт Source Sans.

источник/main/java/main.java:

import com.openhtmltopdf.extend.FSSupplier;
import com.openhtmltopdf.pdfboxout.PdfRendererBuilder;
import org.jsoup.Jsoup;
import org.jsoup.helper.W3CDom;
import org.w3c.dom.Document;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

public class main {
    public static void main(String[] args) {
        System.out.println("Starting");

        try {

            final W3CDom w3cDom = new W3CDom();
            final Document w3cDoc = w3cDom.fromJsoup(Jsoup.parse(readFile()));
            final OutputStream outStream = new FileOutputStream("test.pdf");

            final PdfRendererBuilder pdfBuilder = new PdfRendererBuilder();
            pdfBuilder.useFastMode();
            pdfBuilder.withW3cDocument(w3cDoc, "/");
            pdfBuilder.useFont(new File(main.class.getClassLoader().getResource("fonts/SourceSansPro-Regular.ttf").getFile()), "source-sans");
            pdfBuilder.toStream(outStream);

            pdfBuilder.run();
            outStream.close();

        } catch (Exception e) {
            System.out.println("PDF could not be created: " + e.getMessage());
        }

        System.out.println("Finish.");
    }


    private static String readFile() throws IOException {
        final ClassLoader classLoader = main.class.getClassLoader();
        final InputStream inputStream = classLoader.getResourceAsStream("test.html");
        final StringBuilder sb = new StringBuilder();
        final Reader r = new InputStreamReader(Objects.requireNonNull(inputStream), StandardCharsets.UTF_8);
        char[] buf = new char[1024];
        int amt = r.read(buf);
        while(amt > 0) {
            sb.append(buf, 0, amt);
            amt = r.read(buf);
        }
        return sb.toString();
    }
}
  • Не беспокойтесь о второй функции, она просто читает файл HTML и включена здесь только для того, чтобы иметь полную программу.

src/main/resources/fonts/SourceSansPro-regular.ttf

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>paf</groupId>
    <artifactId>test</artifactId>
    <version>1.0-SNAPSHOT</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>7</source>
                    <target>7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>com.openhtmltopdf</groupId>
            <artifactId>openhtmltopdf-pdfbox</artifactId>
            <version>0.0.1-RC18</version>
        </dependency>
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.11.2</version>
        </dependency>
    </dependencies>
</project>

Вывод программы:

Starting
com.openhtmltopdf.load INFO:: TIME: parse stylesheets  148ms
com.openhtmltopdf.match INFO:: media = print
com.openhtmltopdf.match INFO:: Matcher created with 147 selectors
com.openhtmltopdf.load INFO:: Loading font(source-sans) from InputStream supplier now.
com.openhtmltopdf.exception WARNING:: bad URL given: /fonts/SourceSansPro-Regular.ttf
com.openhtmltopdf.exception WARNING:: Could not load @font-face font: /fonts/SourceSansPro-Regular.ttf
com.openhtmltopdf.exception WARNING:: Font metrics not available. Probably a bug.
com.openhtmltopdf.exception WARNING:: Font metrics not available. Probably a bug.
com.openhtmltopdf.render WARNING:: Font is null.
com.openhtmltopdf.render WARNING:: Font is null.
com.openhtmltopdf.render WARNING:: Font is null.
com.openhtmltopdf.render WARNING:: Font is null.
com.openhtmltopdf.render WARNING:: Font is null.
com.openhtmltopdf.render WARNING:: Font is null.
com.openhtmltopdf.render WARNING:: Font is null.
Finish.

Итоговый PDF

Latin Script
##### ######## #######.
  • Шрифт с засечками.

Редактировать 1: Различные изменения в соответствии со страницами, на которые есть ссылки в комментариях, и обновлены до RC18. теперь новый вывод, но шрифт в PDF по-прежнему неправильный.


Редактировать 2: попробовал быстрый рендерер


person Paflow    schedule 25.03.2019    source источник
comment
Я думаю, вам следует задать этот вопрос в системе отслеживания проблем openhtmltopdf (если только они не направили вас сюда). На самом деле это не вопрос PDFBox, сам PDFBox может использовать шрифты Unicode с версии 2.0.0.   -  person Tilman Hausherr    schedule 25.03.2019
comment
Также посмотрите здесь github.com/danfickle/openhtmltopdf/wiki/Fonts и github.com/danfickle/openhtmltopdf/issues/20 может быть, это поможет?   -  person Tilman Hausherr    schedule 25.03.2019
comment
И используйте последнюю версию 0.0.1-RC18, а не 0.0.1-RC12. Также рассмотрите возможность использования плагина версий maven.   -  person Tilman Hausherr    schedule 25.03.2019
comment
Спасибо вам обоим. Я изменил способ загрузки шрифта и теперь использую версию TTF вместо OTF в соответствии со связанными страницами. Я также обновился до RC18. Вывод теперь другой, но он все еще не работает. Я думаю, что мне действительно следует опубликовать это в системе отслеживания проблем GitHub openhtmltopdf.   -  person Paflow    schedule 25.03.2019


Ответы (1)


Хорошо. Благодаря комментариям @Tilman Hausherr я спросил в GitHub-Issue Tracker о openhtmltopdf и получил некоторую помощь< /а>.

Эти изменения заставили его работать, если кто-то, приземлившийся здесь, заинтересован:

src/main/java/main.java (только измененная часть, остальное см. выше):

    public static void main(String[] args) {
        System.out.println("Starting");

        try {

            final W3CDom w3cDom = new W3CDom();
            final Document w3cDoc = w3cDom.fromJsoup(Jsoup.parse(readFile()));
            final OutputStream outStream = new FileOutputStream("test.pdf");

            final PdfRendererBuilder pdfBuilder = new PdfRendererBuilder();
            pdfBuilder.useFastMode();
            pdfBuilder.withW3cDocument(w3cDoc, "/");
            pdfBuilder.useFont(new File(main.class.getClassLoader().getResource("fonts/SourceSansPro-Regular.ttf").getFile()), "source-sans");
            pdfBuilder.toStream(outStream);

            pdfBuilder.run();
            outStream.close();

        } catch (Exception e) {
            System.out.println("PDF could not be created: " + e.getMessage());
        }

        System.out.println("Finish.");
    }

src/main/resources/fonts/SourceSansPro-regular.ttf

из src/main/resources/test.html (только измененная часть, остальные см. выше)

        @font-face {
            font-family: 'source-sans';
            font-style: normal;
            font-weight: 400;
            src: url(fonts/SourceSansPro-Regular.ttf);
            -fs-font-subset: complete-font;
        }
person Paflow    schedule 27.03.2019
comment
Есть ли изменения в основном методе? - person ZehnVon12; 02.01.2020
comment
Видимо нет. - person Paflow; 02.01.2020
comment
@Paflow, как я могу использовать шрифт в качестве InputStream Java в этом методе useFont. - person Somnath Singh; 22.02.2021