How to generate mutiple page using PdfWriter

时间:2015-10-29 11:07:59

标签: c# pdf-generation itextsharp itextpdf

I am generating pdf file for payslip using PdfWriter in C#. And I'm downloading the pdf file from html code, every user it will create a table (<table>...</table>) and every table display in new page. But all table are displayed in same page.

eg

Page 1
Employee 1 Details
may the details will come to the next page.

Page 2
Employee 2 Details

Page 3
Employee 2 details
Page 4
Employee 3 details

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

But Now my output will come
Page 1
Employee 1
Employee 2
Page 2
Employee 3
Employee 4
Employee 5
.....

My code is

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 个答案:

答案 0 :(得分:1)

您正在使用HTMLWorker。该类已被弃用:它已不再受支持,因为它已被放弃以支持XML Worker。有不同的方法可以解决您的问题。

创建多个小型HTML文件,而不是一个大HTML

我不会为每个员工创建一个长表,而是为每个员工创建一个表,并在添加每个表后引入document.NewPage()。 请参阅问题How to parse multiple HTML files into a single PDF?

回答#2

这是一些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();
}

从内存和CPU使用的角度来看,此解决方案是最佳解决方案。

创建一个大HTML并引入分页符

另一个选择是在每个员工表之前引入分页符。见set new page in HTML using iTextSharp HTMLWorker (html to pdf)

这不是一个好主意,因为您在内存中构建了大量数据,并且只能在呈现PDF后释放内存。 iTextSharp尝试尽快将页面刷新到OutputStream。如果您创建小的HTML文件,并立即将它们添加到PDF中,您可以尽快从内存中丢弃HTML字节,iTextSharp也可以将内容流刷新到输出,释放存储该内容所需的内存

重要提示:

显然,这些答案意味着你做对了。那就是:丢弃依赖于被遗弃的HTMLWorker的代码并开始使用XML Worker。

答案 1 :(得分:0)

您可以在每个标记之后附加分页符,并在标记之前附加。 这会给你一个像, .................

以下是拆分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

答案 2 :(得分:-1)

如果您的html内容已修复,那么您可以使用分页符,但如果您的HTML内容是可变的,那么预测页面何时开始和结束将有所不同。