【问题标题】:How to generate mutiple page using PdfWriter如何使用 PdfWriter 生成多个页面
【发布时间】:2016-01-29 11:54:39
【问题描述】:

我正在使用 C# 中的 PdfWriter 为工资单生成 pdf 文件。我正在从 html 代码下载 pdf 文件,每个用户都会创建一个表格 (

...
) 并且每个表格都显示在新页面中。 但是所有表格都显示在同一页面中。

例如

第 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();

【问题讨论】:

    标签: c# pdf-generation itextsharp itextpdf


    【解决方案1】:

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

    【讨论】:

    • html内容不一样,怎么办?
    • 那么您需要编写整个打印库,例如 A4 大小的总字符内容计数。因此,根据您的 html 内容,您需要对页码进行一些数学计算。这不是一个强大的解决方案,但希望它能起作用
    • 亲爱的@jalil,很抱歉,但我不明白您的回答如何解决问题。您可能想要生成一些代码来说明您的意思。
    【解决方案2】:

    您正在使用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。

    【讨论】:

      【解决方案3】:

      您可以在每个标签之后附加分页符并在标签之前附加。 这会给你一个类似的字符串, ....................

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-08-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多