Как создать действительный файл PDF / A с использованием iText и XMLWorker (процесс HTML в PDF / A)

В настоящее время я разрабатываю метод, который будет принимать ввод HTML и преобразовывать его в действительный файл PDF / A. Я знаю, как программно создать правильный файл PDF / A, используя iText (ссылка:http://itextsupport.com/download/pdfa3.html) но я не могу сгенерировать действительный файл PDF / A, используя HTML в качестве входных данных и используя XMLWorker для преобразования этого ввода в PDF-файл. Проблема, которая у меня есть сейчас, связана с требованием встроенных шрифтов формата PDF / A. Я всегда получаю это исключение:

Исключение в потоке "main" com.itextpdf.text.pdf.PdfAConformanceException: все шрифты должны быть встроены. Это не Helvetica

Я пытаюсь определить, какие шрифты будут использовать ввод HTML через CSS-файл, и я регистрирую шрифты, которые хочу использовать в выходном PDF-файле, через класс XMLWorkerFontProvider, но, похоже, я делаю что-то не так, потому что исключение, приведенное выше, всегда выброшены.

Что еще мне нужно для того, чтобы XMLWorker использовал шрифты, зарегистрированные через класс XMLWorkerFontProvider? Я хочу избежать использования шрифта по умолчанию Helvetica в каждом элементе HTML, присутствующем во входных данных.

Ниже приведен код, который я использую для тестирования:

style.css (всего 1 строка):

* { font: normal 100% Arial, sans-serif !important; }

Main.java:

package com.itextpdf;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringReader;

import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.ICC_Profile;
import com.itextpdf.text.pdf.PdfAConformanceLevel;
import com.itextpdf.text.pdf.PdfAWriter;
import com.itextpdf.tool.xml.XMLWorker;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.itextpdf.tool.xml.css.CssFile;
import com.itextpdf.tool.xml.css.StyleAttrCSSResolver;
import com.itextpdf.tool.xml.html.CssAppliers;
import com.itextpdf.tool.xml.html.CssAppliersImpl;
import com.itextpdf.tool.xml.html.Tags;
import com.itextpdf.tool.xml.parser.XMLParser;
import com.itextpdf.tool.xml.pipeline.css.CSSResolver;
import com.itextpdf.tool.xml.pipeline.css.CssResolverPipeline;
import com.itextpdf.tool.xml.pipeline.end.PdfWriterPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {

        StringBuffer buf = new StringBuffer();

        buf.append("<!DOCTYPE html>");
        buf.append("<html>");
        buf.append("<head>");
        buf.append("<title>Test</title>");
        buf.append("</head>");
        buf.append("<body>");
        buf.append("<p>This is a test</p>");
        buf.append("</body>");
        buf.append("</html>");

        OutputStream file = null;
        Document document = null;
        PdfAWriter writer = null;

        try {

            file = new FileOutputStream(new File("C:\\Users\\amartin\\Desktop\\Test.pdf"));
            document = new Document();
            writer = PdfAWriter.getInstance(document, file, PdfAConformanceLevel.PDF_A_1B);

            // Create XMP metadata. It's a PDF/A requirement.
            writer.createXmpMetadata();

            document.open();

            // Set output intent. PDF/A requirement.
            ICC_Profile icc = ICC_Profile.getInstance(new FileInputStream("./src/main/resources/com/itextpdf/sRGB Color Space Profile.icm"));
            writer.setOutputIntents("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", icc);

            // CSS
            CSSResolver cssResolver = new StyleAttrCSSResolver();
            CssFile cssFile = XMLWorkerHelper.getCSS(new FileInputStream("./css/style.css"));
            cssResolver.addCss(cssFile);

            XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider();
            fontProvider.register("./fonts/arial.ttf");
            fontProvider.register("./fonts/sans-serif.ttf");
            fontProvider.addFontSubstitute("lowagie", "garamond");

            CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
            HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
            htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());

            // Pipelines
            PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);
            HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
            CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);

            XMLWorker worker = new XMLWorker(css, true);
            XMLParser p = new XMLParser(worker);

            Reader reader = new StringReader(buf.toString());
            p.parse(reader);

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            if (document != null && document.isOpen())
                document.close();

            try {

                if (file != null)
                    file.close();

            } catch (IOException e) {}

            if (writer != null && !writer.isCloseStream())
                writer.close();

        }

    }

}

редактировать:

Отвечая Бруно, я расширил класс FontFactoryImp, переопределяя метод getFont () (тот, который имеет все аргументы). Он вызывает функцию System.out.println следующим образом:

System.out.println("=fontname: " + fontname + " =encoding: " + encoding + " =embedded : " + embedded + " =size: " + size + " =style: " + style + " =BaseColor: " + color)

и затем вызывает метод parent.getFont () с теми же аргументами. Единственный вывод, который я вижу, это:

= fontname: null = кодировка: Cp1252 = встроенный: true = размер: -1.0 = стиль: -1 = BaseColor: null = имя шрифта: null = кодировка: Cp1252 = встроенный: true = размер: -1.0 = стиль: -1 = BaseColor : ноль

и исключение, вставленное перед этим кодом.

Ответы на вопрос(2)

Ваш ответ на вопрос