C# 我遗漏了什么步骤,或者我的顺序不正确,导致PDF编写失败?

C# 我遗漏了什么步骤,或者我的顺序不正确,导致PDF编写失败?,c#,pdf,itextsharp,filestream,C#,Pdf,Itextsharp,Filestream,我有一个生成PDF文件的代码,但它无法打开,Edge在我尝试时告诉我,“无法打开PDF。有什么东西阻止打开此PDF。” 以下是不知怎么搞砸了/乱七八糟的代码(省略了非永久性和冗余代码): 我看到“文件已写入”messagebox.show,但随后出现“无法访问封闭流” 更新 我现在正在创建MemoryStream,但没有使用“关闭”,并在写入之前关闭文档,但我仍然收到一条消息,即PDF文件(尽管它确实有一些内容(2KB))无法打开 我认为“writer”至少是问题的一部分,因为没有它,PDF是0

我有一个生成PDF文件的代码,但它无法打开,Edge在我尝试时告诉我,“无法打开PDF。有什么东西阻止打开此PDF。”

以下是不知怎么搞砸了/乱七八糟的代码(省略了非永久性和冗余代码):

我看到“文件已写入”messagebox.show,但随后出现“无法访问封闭流”

更新 我现在正在创建MemoryStream,但没有使用“关闭”,并在写入之前关闭文档,但我仍然收到一条消息,即PDF文件(尽管它确实有一些内容(2KB))无法打开

我认为“writer”至少是问题的一部分,因为没有它,PDF是0KB的,但是有了它,“writer”就会变灰,好像它没有被使用一样。下面是我现在的代码(只有上面提到的差异):

我没有看到任何异常消息

更新2 好的,这就是工作所需要的:

var ms = new MemoryStream();
using (var doc = new Document(PageSize.A4.Rotate(), 25, 25, 25, 25))
{
    PdfWriter.GetInstance(doc, ms);
    doc.Open();
    . . . // contents added to the file, same as before
    doc.Add(tblHeadings);
} // using doc
var bytes = ms.ToArray();
String PDFFileName = $"ChairmensCounselInfo_{DateTime.Now.ToShortTimeString()}.pdf";
PDFFileName = PDFFileName.Replace(":", "_");
var chairmansPDFFile = $"C:\\AYttFMApp\\{PDFFileName}";
File.WriteAllBytes(chairmansPDFFile, bytes);
MessageBox.Show($"{PDFFileName} written");

在关闭
文档
之前,您正在使用
内存流
创建一个
字节
数组。这将导致PDF不完整

在使用创建文档的的结尾处,PDF已完成(例如,基本交叉引用表已写入),但此时,您已使用不完整的流写入PDF文件

如何解决这个问题

不要使用
use
创建
MemoryStream
。等待
文档
关闭,然后将
内存流
的字节写入PDF文件

更新:

您在更新中没有正确遵循我的建议。你有这样的想法:

var ms = new MemoryStream();
using (var doc = new Document(PageSize.A4.Rotate(), 25, 25, 25, 25))
{
    using (var writer = PdfWriter.GetInstance(doc, ms))
    {
        doc.Open();
        // adding content
        var bytes = ms.ToArray();
        doc.Close();
        // write bytes to a file.
    }
}
正如我前面解释的,这是错误的。您正在将不完整PDF的内容写入名为
bytes
的字节数组。该PDF已损坏,因为它没有交叉引用表。只有在显式或隐式地
Close()
文档时,才会创建交叉引用表。现在,您可以在创建
bytes
数组后显式关闭()文档。那太晚了

你需要这样的东西:

var ms = new MemoryStream();
using (var doc = new Document(PageSize.A4.Rotate(), 25, 25, 25, 25))
{
    var writer = PdfWriter.GetInstance(doc, ms));
    doc.Open();
    // adding content
}
var bytes = ms.ToArray();
// write bytes to a file
如果您不需要
编写器
,您甚至可以执行以下操作:

var ms = new MemoryStream();
using (var doc = new Document(PageSize.A4.Rotate(), 25, 25, 25, 25))
{
    PdfWriter.GetInstance(doc, ms));
    doc.Open();
    // adding content
}
var bytes = ms.ToArray();
// write bytes to a file
只需确保您创建了完整的PDF:

  • 文档
    有机会关闭之前,不要关闭
    编写器
  • 文档有机会关闭之前,不要使用
    ms

  • 在关闭
    文档
    之前,您正在使用
    内存流
    创建一个
    字节
    数组。这将导致PDF不完整

    在使用
    创建文档的的结尾处,PDF已完成(例如,基本交叉引用表已写入),但此时,您已使用不完整的流写入PDF文件

    如何解决这个问题

    不要使用
    use
    创建
    MemoryStream
    。等待
    文档
    关闭,然后将
    内存流
    的字节写入PDF文件

    更新:

    您在更新中没有正确遵循我的建议。你有这样的想法:

    var ms = new MemoryStream();
    using (var doc = new Document(PageSize.A4.Rotate(), 25, 25, 25, 25))
    {
        using (var writer = PdfWriter.GetInstance(doc, ms))
        {
            doc.Open();
            // adding content
            var bytes = ms.ToArray();
            doc.Close();
            // write bytes to a file.
        }
    }
    
    正如我前面解释的,这是错误的。您正在将不完整PDF的内容写入名为
    bytes
    的字节数组。该PDF已损坏,因为它没有交叉引用表。只有在显式或隐式地
    Close()
    文档时,才会创建交叉引用表。现在,您可以在创建
    bytes
    数组后显式关闭()文档。那太晚了

    你需要这样的东西:

    var ms = new MemoryStream();
    using (var doc = new Document(PageSize.A4.Rotate(), 25, 25, 25, 25))
    {
        var writer = PdfWriter.GetInstance(doc, ms));
        doc.Open();
        // adding content
    }
    var bytes = ms.ToArray();
    // write bytes to a file
    
    如果您不需要
    编写器
    ,您甚至可以执行以下操作:

    var ms = new MemoryStream();
    using (var doc = new Document(PageSize.A4.Rotate(), 25, 25, 25, 25))
    {
        PdfWriter.GetInstance(doc, ms));
        doc.Open();
        // adding content
    }
    var bytes = ms.ToArray();
    // write bytes to a file
    
    只需确保您创建了完整的PDF:

  • 文档
    有机会关闭之前,不要关闭
    编写器
  • 文档有机会关闭之前,不要使用
    ms

  • 您在更新中所说的与下面的代码相矛盾。您说您在写入之前关闭文档,但事实并非如此:您在关闭文档之前将
    ms
    写入
    bytes
    。你所做的违背了基本逻辑。另外:当您使用
    时,不需要关闭
    文档
    。我已经更新了我的答案,您现在可以看到如何解释我的初始答案。B。Clay Shannon,你有一个不起作用的代码,试图让它在不知道怎么做的情况下工作。不如从工作代码(如basic)开始,一步一步地进行更改,每次更改后进行测试,看看是什么更改导致了错误。当然,我们可以为您提供有关使用iTextSharp类的提示(@Bruno在这里已经做了很好的工作),但我们不知道您使用的所有其他内容是否如预期的那样工作。@mkl感谢您的澄清。在过去的一年里,我已经回答了B.Clay Shannon提出的许多问题;到目前为止,B.克莱·香农应该已经有了一些使用iTextSharp的经验。不幸的是,这本书似乎是B.Clay Shannon想要使用的唯一资源::d您在更新中所说的内容与下面的代码相矛盾。您说您在写入之前关闭文档,但事实并非如此:您在关闭文档之前将
    ms
    写入
    bytes
    。你所做的违背了基本逻辑。另外:当您使用
    时,不需要关闭
    文档
    。我已经更新了我的答案,您现在可以看到如何解释我的初始答案。B。Clay Shannon,你有一个不起作用的代码,试图让它在不知道怎么做的情况下工作。不如从工作代码(如basic)开始,一步一步地进行更改,每次更改后进行测试,看看是什么更改导致了错误。我们当然可以给你机会