【问题标题】:huge data export in pdf itextsharppdf itextsharp 中的大量数据导出
【发布时间】:2017-09-14 05:22:45
【问题描述】:

我尝试以 PDF 格式导出数据,所以当我导出时......这里我不从 gridview 导出数据,但实际上在这里我在代码中创建虚拟 gridview 并在该网格中绑定数据..我没有显示数据页面中的网格..我尝试下面的代码

    Private Sub ExportGridToPDF()
        Using myMemoryStream As New MemoryStream()

            Dim myDocument As New iTextSharp.text.Document(iTextSharp.text.PageSize.A1, 10.0F, 10.0F, 10.0F, 0.0F)
            ' Dim myDocument As New iTextSharp.text.Document()
            Dim myPDFWriter As PdfWriter = PdfWriter.GetInstance(myDocument, myMemoryStream)

            myDocument.Open()

            ' Add to content to your PDF here...

            Dim sw As New StringWriter()
            Dim hw As New HtmlTextWriter(sw)
            GridView1.AllowPaging = False
            GridView1.DataBind()
            GridView1.RenderControl(hw)
            ' We're done adding stuff to our PDF.
            myDocument.Add(hw)
            myDocument.Close()

            Dim content As Byte() = myMemoryStream.ToArray()

            ' Write out PDF from memory stream.
            Using fs As FileStream = File.Create("eport_PDF.pdf")
                fs.Write(content, 0, CInt(content.Length))
            End Using
        End Using
End Sub

当我运行时显示错误

System.InvalidCastException:无法将“System.Web.UI.HtmlTextWriter”类型的对象转换为“iTextSharp.text.IElement”类型。

在这条线上 myDocument.Add(hw)

我使用内存流,因为当我使用没有内存流的代码时,我使用内存流,然后显示错误 Out of Memory 异常,所以我使用内存流,现在显示不同的错误

【问题讨论】:

  • 我已经更新了我的答案。如果你是一个认真的开发者,你会停止使用 iTextSharp 这个词,你会升级到 iText 7,你会从教程中学习而不是重新发明轮子。

标签: vb.net pdf itext export-to-pdf


【解决方案1】:

Document 对象中的Add() 方法只接受实现IElement 接口的参数。您正在传递一个 HtmlTextWriter 对象。该对象与 iText 完全无关。您认为这可行,这真是太神奇了。

在这个问题中,与您之前发布的问题(其中一些已被删除)一样,您指的是 HTML。您在Add image using itextsharp 中使用了HTMLWorker 和已删除的问题Out Of Memory Exception error itext sharp

如果您想将 HTML 转换为 PDF,您应该升级到 iText 7 并使用pdfHTML add-on。看一下教程,看看HTML到PDF的转换是如何完成的:https://developers.itextpdf.com/content/itext-7-converting-html-pdf-pdfhtml

但是,在对此答案的评论中,您写道:我没有将 HTML 中的数据导出到 PDF。 好的,如果这是真的,那么 为什么在您的代码?这很混乱。

此外,您编写我在代码中创建虚拟网格视图并在其中绑定数据。不幸的是,您没有向我们提供有关该虚拟网格视图格式的任何信息。我想,这是你自己“发明”的东西,但如果是这样,你认为 iText 怎么能神奇地理解你发明的 dummy grid-view

我通过说Add() 方法只接受实现IElement 接口的对象来开始这个答案。由于您在谈论 grid,因此使用 iText 表格元素可能会很有趣。在 iText 5 中,有一个名为 PdfPTable 的对象;在 iText 7 中,该对象被简单命名为 Table

很多人拥有大型数据集,先创建这样一个表对象,然后将其添加到Document。这并不总是明智的,因为对象不断在内存中建立,最终导致OutOfMemoryException。对于大型数据集,应将表格标记为大元素,逐步添加表格。

在 iText 5 中,代码如下所示:

Document document = new Document();
FileStream stream = new FileStream(fileName, FileMode.Create);
var pdfWriter = PdfWriter.GetInstance(document, stream);
document.Open();
PdfPTable table = new PdfPTable(4);
table.Complete = false;
for (int i = 0; i < 1000000; i++) {
    PdfPCell cell = new PdfPCell(new Phrase(i.ToString()));
    table.AddCell(cell);
    if (i > 0 && i % 1000 == 0) {
        document.Add(table);
    }
}
table.Complete = true;
document.Add(table);
document.Close();

我们将 1000000 个单元格添加到一个有 4 列的表格中,但我们每 1000 个单元格添加一次表格(因此每 250 行)。这意味着内容会定期从内存中刷新,从而避免出现OutOfMemoryException

由于您似乎是 iText 的新手,请帮自己一个忙,并升级到使用 iText 7。iText 5 处于维护模式,这意味着该版本不会添加任何新功能。例如:如果在某个时候有人要求您生成 PDF 2.0 文件(PDF 2.0 规范是几个月前发布的),您将不得不扔掉所有 iText 5 代码,重新开始,因为只有 iText 7 会支持PDF 2.0。

iText 7 中的大表格功能,在chapter 5 of the tutorial 末尾讨论:

PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
Document document = new Document(pdf);
Table table = new Table(new[] {1f, 1f, 1f}, true);
table.AddHeaderCell("Table header 1");
table.AddHeaderCell("Table header 2");
table.AddHeaderCell("Table header 3");
table.AddFooterCell("Table footer 1");
table.AddFooterCell("Table footer 2");
table.AddFooterCell("Table footer 3");
document.Add(table);
for (int i = 0; i < 1000; i++)
{
    table.AddCell($"Row {i + 1}; column 1");
    table.AddCell($"Row {i + 1}; column 2");
    table.AddCell($"Row {i + 1}; column 3");
    if (i % 50 == 0)
    {
        table.Flush();
    }
 }
 table.Complete();
 document.Close();

如您所见,iText 7 代码更加直观。我们创建一个有 3 列的表,第二个参数(true)表示我们将添加一个非常大的表。我们添加页眉,添加页脚,然后将表格添加到文档中。然后我们添加 1000 行,但我们每 50 行 Flush() 表。刷新空闲内存,避免内存不足。完成后,我们Complete() 桌子。

所有这些都记录在官方网站上!您无需发明自己的网格视图。正如您所发现的,发明自己的网格视图不可能奏效

同样重要:你说 iTextSharp,我说 iText。我们的意思相同:由 iText Group 生产的 PDF 库,可用于从 C# 代码创建 PDF 文档。只有您在使用旧名称,而我们根据商标的建议尽量避免使用该名称,该商标告诉我们有一家名为 Sharp 的公司不欣赏其他公司在品牌上下文中使用 Sharp 这个词t 与他们的公司有关。 所以请不要再说你在使用 iTextSharp;你正在使用 iText!

【讨论】:

  • 我没有将 HTML 中的数据导出到 pdf 中。我在代码中创建虚拟网格视图并在其中绑定数据。我在按钮单击时直接导出 pdf 中的数据。 ...如果我在该问题上遇到错误,那么我发布了问题 stackoverflow 这并不意味着您总是对我的问题投反对票。.您在开发领域可能比我有更多的经验这并不意味着您通过对他们的问题投反对票来帮助他人...'
  • 好的,请解释一下你为什么使用HtmlTextWriter 对象。为什么您认为这是有道理的,为什么您认为将这样的对象添加到 iText Document 实例会起作用?你在哪里找到了让你相信它会起作用的东西?
  • 拒绝投票的问题是为了保持 Stack Overflow 的清洁。它旨在阻止不认真的人,例如学生使用 Stack Overflow 让其他人做作业,或者阻止懒惰的开发人员要求别人为他们做工作。就您而言,Stack Overflow 不能替代教育。当然,您可以从 Stack Overflow 学到很多东西,但 Stack Overflow 并不能取代获得计算机科学学位。出于某种原因,您不理解给出的答案。要么你是出于恶意,要么你没有受过足够的教育而无法理解。
  • @user123 我再给你一次学习的机会。我会更新我的答案,如果你不(不想)理解那个解释,我会放弃你。而且我从经验中知道,如果我放弃你,很多人也会放弃你。
  • 虚拟 gridview 的意思是这样的.... Dim GridView1 As New GridView 我没有在页面中显示该网格
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-03
  • 1970-01-01
  • 2013-08-25
相关资源
最近更新 更多