Как создать многостраничную страницу с помощью PdfWriter

Я генерирую PDF-файл для платежного листа, используя PdfWriter в C#. И я загружаю файл PDF из HTML-кода, каждый пользователь создает таблицу (

...), и каждая таблица отображается на новой странице. Но все таблицы отображаются на одной странице.

например

Страница 1
Сотрудник 1 Подробности
Возможно, подробности будут приведены на следующей странице.

Страница 2
Сотрудник 2 Подробности

Страница 3
2 сотрудника
Страница 4
3 сотрудника

.....
.....
....

Но теперь мой вывод придет
Страница 1
Сотрудник 1
Сотрудник 2
Страница 2
Сотрудник 3
Сотрудник 4
Сотрудник 5
.....

Мой код

StringBuilder stb = new StringBuilder();
stb.Append(All.ToString());
EXP.InnerHtml = stb.ToString();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename=" + filename + ".pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);

StringWriter stringWriter = new StringWriter();
HtmlTextWriter htmlTextWriter = new HtmlTextWriter(stringWriter);


string resHtml = "";

for(int i=0;i<10;i++)
{
    resHtml+="<table width='100%'><tr><td align='center'>payslip"+ i+"</td></tr></table>"; 
}
StringReader stringReader = new StringReader(resHtml);
Doc = new Document(PageSize.A2, 10f, 10f, 50f, 20f);

HTMLWorker htmlparser = new HTMLWorker(Doc);
PdfWriter.GetInstance(Doc, Response.OutputStream);
Doc.Open();
htmlparser.Open(); 
htmlparser.Parse(stringReader);
htmlparser.Close();
Doc.Close();
Response.Write(Doc);
Response.End();

3 ответа

Решение

Ты используешь HTMLWorker, Этот класс устарел: он больше не поддерживается, так как был заброшен в пользу XML Worker. Есть разные способы решить вашу проблему.

Создайте несколько маленьких файлов HTML вместо одного большого HTML

Я бы не создавал одну длинную таблицу для каждого сотрудника, а одну таблицу для каждого сотрудника, и представлял бы document.NewPage() после добавления каждой таблицы. См. Ответ №2 на вопрос " Как разобрать несколько файлов HTML в один PDF-файл?".

Это некоторый Java-код (вы можете прочитать его, как если бы это был псевдокод):

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

Это решение является лучшим решением с точки зрения использования памяти и процессора.

Создать один большой HTML и ввести разрывы страниц

Другим вариантом является введение разрыва страницы перед каждым рабочим столом. См. Набор новой страницы в HTML с помощью iTextSharp HTMLWorker (html to pdf)

Это не очень хорошая идея, поскольку вы создаете большой кусок данных в памяти, и эта память может быть освобождена только после рендеринга PDF. iTextSharp пытается сбросить страницы на OutputStream так скоро, как возможно. Если вы создаете небольшие HTML-файлы и немедленно добавляете их в PDF, вы можете скорее отбрасывать байты HTML из памяти, чем раньше, и iTextSharp также сможет сбрасывать потоки содержимого на выход, освобождая память, необходимую для хранения этого содержимого.,

Важное замечание:

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

Вы можете добавлять разрыв страницы после каждого тега и добавлять перед тегом. Это даст вам строку, как, .................

Ниже приведен код для разделения строки HTML.

Dim myString As String = sb.ToString()
Dim mySplit As String = "pagebreak"
Dim myResult() As String = myString.Split(New String() {mySplit}, StringSplitOptions.None)

Чтобы отобразить каждую строку HTML на новой странице,

Dim pdfDoc As New Document(PageSize.A4, 10.0F, 10.0F, 10.0F, 0.0F)
        Dim htmlparser As New HTMLWorker(pdfDoc)
        Using memoryStream As New MemoryStream()
            Dim writer As PdfWriter = PdfWriter.GetInstance(pdfDoc, memoryStream)
            pdfDoc.Open()
            For Each r As String In myResult
                Dim sr As New StringReader(r)
                htmlparser.Parse(sr)
                pdfDoc.NewPage()
                sr.Dispose()
            Next
            pdfDoc.Close()
            Dim bytes As Byte() = memoryStream.ToArray()
            memoryStream.Close()
            Response.Clear()
            Response.ContentType = "application/pdf"
            Response.AddHeader("Content-Disposition", "attachment;filename=Report.pdf")
            Response.Buffer = True
            Response.Cache.SetCacheability(HttpCacheability.NoCache)
            Response.BinaryWrite(bytes)
            Response.[End]()
            Response.Close()
        End Using

Если ваш HTML-контент фиксирован, то вы можете с разрывом страницы, но если ваш HTML-контент является переменным, он будет другим, чтобы предсказать, когда страница начнется и закончится.

Другие вопросы по тегам