@DanielASathishKumar "Размер файла HTML составляет почти 1 ГБ". Надеюсь, вы ссылаетесь не только на HTML, но и на размер изображений и файлов, связанных с ним, и мне интересно, действительно ли вам нужны эти огромные файлы, встроенные в PDF. Возможно, вместо ссылки на корпоративный / публичный сервер?

у этот вопрос, потому что многие разработчики задают более или менее один и тот же вопрос в разных формах. Я сам отвечу на этот вопрос (я являюсь основателем / техническим директором iText Group), так что это может быть «Вики-ответ». Если бы функция «документирования» переполнения стека все еще существовала, это было бы хорошим кандидатом на тему документации.

Исходный файл:

Я пытаюсь преобразовать следующий файл HTML в PDF:

<html>
    <head>
        <title>Colossal (movie)</title>
        <style>
            .poster { width: 120px;float: right; }
            .director { font-style: italic; }
            .description { font-family: serif; }
            .imdb { font-size: 0.8em; }
            a { color: red; }
        </style>
    </head>
    <body>
        <img src="img/colossal.jpg" class="poster" />
        <h1>Colossal (2016)</h1>
        <div class="director">Directed by Nacho Vigalondo</div>
        <div class="description">Gloria is an out-of-work party girl
            forced to leave her life in New York City, and move back home.
            When reports surface that a giant creature is destroying Seoul,
            she gradually comes to the realization that she is somehow connected
            to this phenomenon.
        </div>
        <div class="imdb">Read more about this movie on
            <a href="www.imdb.com/title/tt4680182">IMDB</a>
        </div>
    </body>
</html>

В браузере этот HTML выглядит так:

Проблемы, с которыми я столкнулся:

HTMLWorker вообще не учитывает CSS

Когда я использовалHTMLWorkerМне нужно создатьImageProvider чтобы избежать ошибки, которая сообщает мне, что изображение не может быть найдено. Мне также нужно создатьStyleSheet Например, чтобы изменить некоторые стили:

public static class MyImageFactory implements ImageProvider {
    public Image getImage(String src, Map<String, String> h,
            ChainedProperties cprops, DocListener doc) {
        try {
            return Image.getInstance(
                String.format("resources/html/img/%s",
                    src.substring(src.lastIndexOf("/") + 1)));
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }    
}

public static void main(String[] args) throws IOException, DocumentException {
    Document document = new Document();
    PdfWriter.getInstance(document, new FileOutputStream("results/htmlworker.pdf"));
    document.open();
    StyleSheet styles = new StyleSheet();   
    styles.loadStyle("imdb", "size", "-3");
    HTMLWorker htmlWorker = new HTMLWorker(document, null, styles);
    HashMap<String,Object> providers = new HashMap<String, Object>();
    providers.put(HTMLWorker.IMG_PROVIDER, new MyImageFactory());
    htmlWorker.setProviders(providers);
    htmlWorker.parse(new FileReader("resources/html/sample.html"));
    document.close();   
}

Результат выглядит так:

По какой-то причинеHTMLWorker также показывает содержание<title> тег. Я не знаю, как этого избежать. CSS в заголовке не анализируется вообще, я должен определить все стили в моем коде, используяStyleSheet объект.

Когда я смотрю на свой код, я вижу, что многие объекты и методы, которые я использую, устарели:

Поэтому я решил перейти на использование XML Worker.

Изображения не найдены при использовании XML Worker

Я попробовал следующий код:

public static final String DEST = "results/xmlworker1.pdf";
public static final String HTML = "resources/html/sample.html";
public void createPdf(String file) throws IOException, DocumentException {
    Document document = new Document();
    PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
    document.open();
    XMLWorkerHelper.getInstance().parseXHtml(writer, document,
            new FileInputStream(HTML));
    document.close();
}

Это привело к следующему PDF:

Вместо Times-Roman используется шрифт по умолчанию Helvetica; это типично для iText (я должен был явно определить шрифт в моем HTML). В противном случае, кажется, что CSS соблюдается, но изображение отсутствует, и я не получил сообщение об ошибке.

С участиемHTMLWorkerвозникло исключение, и я смог решить проблему, введяImageProvider, Давайте посмотрим, работает ли это для XML Worker.

Не все стили CSS поддерживаются в XML Worker

Я адаптировал свой код так:

public static final String DEST = "results/xmlworker2.pdf";
public static final String HTML = "resources/html/sample.html";
public static final String IMG_PATH = "resources/html/";
public void createPdf(String file) throws IOException, DocumentException {
    Document document = new Document();
    PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
    document.open();

    CSSResolver cssResolver =
            XMLWorkerHelper.getInstance().getDefaultCssResolver(true);
    HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
    htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
    htmlContext.setImageProvider(new AbstractImageProvider() {
        public String getImageRootPath() {
            return IMG_PATH;
        }
    });

    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);
    p.parse(new FileInputStream(HTML));

    document.close();
}

Мой код намного длиннее, но теперь изображение отображается:

Изображение больше, чем когда я рендерил его, используяHTMLWorker который говорит мне, что атрибут CSSwidth дляposter класс учитывается, ноfloat атрибут игнорируется. Как я могу это исправить?

Оставшийся вопрос:

Итак, вопрос сводится к следующему: у меня естьконкретный HTML-файл, который я пытаюсь преобразовать в PDF. Я проделал большую работу, решая одну проблему за другой, но есть однаконкретный проблема, которую я не могу решить: как заставить iText уважать CSS, который определяет положение элемента, напримерfloat: right?

Дополнительный вопрос:

Когда мой HTML содержит элементы формы (такие как<input>), эти элементы формы игнорируются.

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

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