Прежде чем мы начнем: Я не разработчик 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).
Я вижу, что этот вопрос уже получил два downvotes, но я думаю, что вопрос можно сохранить при условии добавления разъяснений. (1.) Замените «HtmlWorker» на XML Worker (потому что «HtmlWorker» больше не поддерживается и не будет отвечать вашим потребностям). (2.) напишите некоторый псевдокод, который позволяет правильно интерпретировать ваш вопрос. Вы хотите создать 1 PDF-файл, который заполнен содержимым из серии файлов HTML, но что такое «разбиение на страницы»? Вы хотите создать новую страницу для каждого нового HTML-файла? Просьба уточнить. –
Я хочу создать 1 PDF с серией HTML, например, HTML1 - первая страница, html2 - вторая страница, все htmls находятся в том же формате pdf – kyzh101
Отлично, я обновлю ваш вопрос в надежде, что люди, которые проголосовали, чтобы закрыть ваш вопрос, пересматривая ;-) –