2015-01-07 2 views
3

Я хочу использовать iText для преобразования серии html-файла в PDF.Как разобрать несколько файлов HTML в один PDF-файл?

Например: если эти файлы:

  • page1.html
  • page2.html
  • page3.html
  • ...

Теперь я хочу, чтобы создать один файл PDF, где page1.html - первая страница, страница2.html - вторая страница и т. д.

Я знаю, как конвертировать один файл HTML в PDF, но я не знаю, как объединить эти разные PDF-файлы, полученные в результате этой операции, в один PDF-файл.

+0

Я вижу, что этот вопрос уже получил два downvotes, но я думаю, что вопрос можно сохранить при условии добавления разъяснений. (1.) Замените «HtmlWorker» на XML Worker (потому что «HtmlWorker» больше не поддерживается и не будет отвечать вашим потребностям). (2.) напишите некоторый псевдокод, который позволяет правильно интерпретировать ваш вопрос. Вы хотите создать 1 PDF-файл, который заполнен содержимым из серии файлов HTML, но что такое «разбиение на страницы»? Вы хотите создать новую страницу для каждого нового HTML-файла? Просьба уточнить. –

+0

Я хочу создать 1 PDF с серией HTML, например, HTML1 - первая страница, html2 - вторая страница, все htmls находятся в том же формате pdf – kyzh101

+0

Отлично, я обновлю ваш вопрос в надежде, что люди, которые проголосовали, чтобы закрыть ваш вопрос, пересматривая ;-) –

ответ

7

Прежде чем мы начнем: Я не разработчик C#, поэтому я не могу привести вам пример на C#. Все примеры iText, которые я пишу, написаны на Java. К счастью, iText и iTextSharp всегда синхронизируются. В контексте этого вопроса вы можете быть уверены, что все, что работает для iText, также будет работать для iTextSharp, но вам придется сделать небольшие адаптации, характерные для C#. Из того, что я слышу от разработчиков C#, этого обычно не сложно добиться.

Относительно ответа: есть два ответа, а ответ # 2 обычно лучше ответа # 1, но я даю оба варианта, потому что могут быть конкретные случаи, когда ответ # 1 лучше.

Тестовые данные: Я создал 3 простых HTML-файлов, каждый из которых содержит некоторую информацию о государстве в США:

Мы будем использовать XML Worker для анализа этих трех файлов, и мы хотим, чтобы спеть le PDF-файл.

Ответ # 1: см ParseMultipleHtmlFiles1 для полной выборки коды и multiple_html_pages1.pdf для итогового PDF.

Вы говорите, что вам уже удалось преобразовать один файл HTML в один файл PDF. Предполагается, что вы сделали это так:

public byte[] parseHtml(String html) throws DocumentException, IOException { 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    // step 1 
    Document document = new Document(); 
    // step 2 
    PdfWriter writer = PdfWriter.getInstance(document, baos); 
    // step 3 
    document.open(); 
    // step 4 
    XMLWorkerHelper.getInstance().parseXHtml(writer, document, 
      new FileInputStream(html)); 
    // step 5 
    document.close(); 
    // return the bytes of the PDF 
    return baos.toByteArray(); 
} 

Это не самый эффективный способ для разбора файла HTML (есть и другие примеры на веб-сайте), но это самый простой способ.

Как вы можете видеть, этот метод анализирует HTML в PDF-файл и возвращает этот PDF-файл в виде byte[]. Поскольку мы хотим создать один PDF-файл, мы можем передать этот массив байтов в экземпляр PdfCopy, чтобы мы могли объединить несколько документов.

Предположим, что у нас есть три документа:

public static final String[] HTML = { 
    "resources/xml/page1.html", 
    "resources/xml/page2.html", 
    "resources/xml/page3.html" 
}; 

Мы перебираем этих трех документов, синтаксический анализ их по одному к byte[], создать PdfReader экземпляр с PDF байтов и добавить документ в PdfCopy экземпляра с помощью addDocument() метода:

public void createPdf(String file) throws IOException, DocumentException { 
    Document document = new Document(); 
    PdfCopy copy = new PdfCopy(document, new FileOutputStream(file)); 
    document.open(); 
    PdfReader reader; 
    for (String html : HTML) { 
     reader = new PdfReader(parseHtml(html)); 
     copy.addDocument(reader); 
     reader.close(); 
    } 
    document.close(); 
} 

Это решает проблему, но почему я думаю, что это не является оптимальным решением?

Предположим, что вам нужно использовать специальный шрифт, который необходимо встроить. В этом случае каждый отдельный PDF-файл будет содержать подмножество этого шрифта. Для разных файлов потребуются разные подмножества шрифтов, а PdfCopy (а не PdfSmartCopy, если на то пошло) могут объединять подмножества шрифтов. Это может привести к раздутому PDF-файлу со слишком большим количеством подмножеств шрифтов того же шрифта.

Как это решить? Это объясняется в ответе №2.

Ответ # 2: См ParseMultipleHtmlFiles2 для полной выборки коды и multiple_html_pages2.pdf для результирующего PDF. Вы уже видите разницу в размере файла: 4.61 КБ против 5.05 КБ (и мы даже не вводили встроенные шрифты).

В этом случае мы не разбираем HTML-файл в формате PDF так, как мы это делали в методе parseHtml() из ответа №1. Вместо этого мы анализируем HTML до iText ElementList с использованием метода parseToElementList(). Этот метод требует двух String с. Один, содержащий HTML-код, другой, содержащий значения CSS.

Мы используем служебный метод для чтения HTML-файла в String. Что касается значения CSS, мы могли бы пройти null до parseToElementList(), но в этом случае стили по умолчанию будут игнорироваться. Вы заметите, что тег <h1>, который мы ввели в наш HTML, будет выглядеть совершенно по-другому, если вы не передадите default.css, который поставляется с XML Worker.

Короче говоря, это код:

public void createPdf(String file) throws IOException, DocumentException { 
    Document document = new Document(); 
    PdfWriter.getInstance(document, new FileOutputStream(file)); 
    document.open(); 
    String css = readCSS(); 
    for (String htmlfile : HTML) { 
     String html = Utilities.readFileToString(htmlfile); 
     ElementList list = XMLWorkerHelper.parseToElementList(html, css); 
     for (Element e : list) { 
      document.add(e); 
     } 
     document.newPage(); 
    } 
    document.close(); 
} 

Мы создаем единый Document и один PdfWriter экземпляр. Мы анализируем разные HTML-файлы в ElementList s один за другим, и мы добавляем все элементы в Document.

Как вы хотите создать новую страницу, каждый раз, когда обрабатывается новый HTML-файл, я ввел document.newPage(). Если вы удалите эту строку, вы можете добавить три страницы HTML на одну страницу (что было бы невозможно, если бы вы выбрали ответ №1).

+0

Я использовал два вышеупомянутых ответа для преобразования, но css потерян, это мой html. [Link] (http://prototype.ui.sh.ctriptravel.com/gerrit/gbk/master/UED/Flight/UED .Flight.online, _prototype_/print/fltInt_multi_itinerary.html) – kyzh101

+0

Привет, мистер Бруно Лоугай, Кажется, iTextSharp не может обнаружить какой-то особый стиль css – kyzh101

+0

. Ссылки показывают страницу «Этот домен, возможно, для продажи. «. Обратите внимание: XML Worker может выполнять только XHTML2PDF, ** NOT ** URL2PDF. iTextSharp отправляет страницы в 'OutputStream', как только они будут завершены. Это исключает CSS-конструкции, которые добавляются в конце HTML-файла, но для этого требуется, чтобы контент был добавлен на первую страницу. HTML очень отличается от PDF. Просто попробуйте распечатать HTML-страницу из браузера, и уже вы столкнетесь с ограничениями конвертации HTML на страницы с фиксированным размером. –

Смежные вопросы