使用内存流的正确方法:无法访问封闭流

时间:2014-11-28 11:20:17

标签: c# asp.net memory stream

我尝试在内存中创建PDF,并在用户点击时下载。

在检查时,output会返回Cannot access closed stream

Cannot access closed stream

我已经阅读了一些关于同一问题的帖子,但我仍然无法解决。

有人能指出我正确的方向吗?我错过了什么吗?

这是我在click事件处理程序中调用的函数。

protected MemoryStream printSelectionPDF()
        {
            var output = new MemoryStream();
            var doc = new Document(PageSize.A4);
            var writer = PdfWriter.GetInstance(doc, output);

            string Sur = DropDownListSurname.SelectedValue;
            string Cat = DropDownListCategory.SelectedItem.Text;
            string Pos = DropDownListPosition.SelectedItem.Text;
            string Resp = DropDownListResp.SelectedValue;

            doc.SetMargins(36, 36, 18, 18);

            GridView1.AllowPaging = false;
            GridView1.DataBind();
            doc.Open();
            CreatePDF(doc, rdBtnStaff.Checked, IncludeHistoricCheckBox.Checked, Sur, Cat, Pos, Resp);
            doc.Close();
            GridView1.AllowPaging = true;
            return output;
        }

这是我创建PDF文档的地方。

protected void CreatePDF(Document pdfDoc, bool Staff, bool includeHistoric, string Surname, string Category, string Position, string Responsibility)
        {

            //font
            BaseFont bfTimes = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, false);
            Font normalFont = new Font(bfTimes, 9f, Font.NORMAL, BaseColor.BLACK);
            Font titleFont = new Font(bfTimes, 11f, Font.BOLD, BaseColor.BLACK);
            Font timeFont = new Font(bfTimes, 10f, Font.NORMAL, BaseColor.BLACK);
            Font headerFont = new Font(bfTimes, 9f, Font.BOLD, BaseColor.BLACK);
            Font cellFont = new Font(bfTimes, 9f, Font.NORMAL, BaseColor.BLACK);
            Font cellFontRed = new Font(bfTimes, 9f, Font.NORMAL, BaseColor.RED);

            //Title
            pdfDoc.Add(new Paragraph("People Report", titleFont));
            pdfDoc.Add(new Paragraph(" "));
            pdfDoc.Add(new Paragraph("Number of records found: " + GridView1.Rows.Count, headerFont));
            PdfPTable table = new PdfPTable(6);
            table.SpacingBefore = 4;
            table.SpacingAfter = 8;
            table.WidthPercentage = 100;

            //Headers
            //starts from 1 in order to exclude invisible dynamicHyperlink
            for (int j = 1; j < GridView1.Columns.Count; j++)
            {
                string colHeader = GridView1.Columns[j].HeaderText;
                table.AddCell(new Phrase(colHeader, headerFont));
            }

            table.HeaderRows = 1;

            using (ASCDataContext asc = new ASCDataContext())
            {

                        IQueryable<vwPeopleCurrentPosition> persons = asc.vwPeopleCurrentPositions
                                                             .Where(p => p.PersonCategoryID == 5)
                                                             .Where(p => String.IsNullOrEmpty(Surname) || p.Surname == Surname)
                                                             .Where(p => String.IsNullOrEmpty(Category) || Category == "All" || p.PersonCategory == Category)
                                                             .Where(p => String.IsNullOrEmpty(Position) || Position == "All" || p.PositionDescription == Position)
                                                             .Where(p => String.IsNullOrEmpty(Responsibility) || p.FellowsResponsibility == Responsibility)
                                                             .Select(p => p)
                                                             .OrderBy(p => p.Surname);
                        foreach (vwPeopleCurrentPosition p in persons)
                        {

                            PdfPCell NameCell = new PdfPCell(new Paragraph(p.Name, cellFont));
                            NameCell.Colspan = 1;
                            NameCell.Border = PdfPCell.NO_BORDER;
                            table.AddCell(NameCell);

                            PdfPCell CategoryCell = new PdfPCell(new Paragraph(p.PersonCategory, cellFont));
                            CategoryCell.Colspan = 1;
                            CategoryCell.Border = PdfPCell.NO_BORDER;
                            table.AddCell(CategoryCell);

                            PdfPCell DescriptionCell = new PdfPCell(new Paragraph(p.PositionDescription, cellFont));
                            DescriptionCell.Colspan = 1;
                            DescriptionCell.Border = PdfPCell.NO_BORDER;
                            table.AddCell(DescriptionCell);

                            PdfPCell TopicCell = new PdfPCell(new Paragraph(p.Description, cellFont));
                            TopicCell.Colspan = 1;
                            TopicCell.Border = PdfPCell.NO_BORDER;
                            table.AddCell(TopicCell);

                            PdfPCell ResponsibilityCell = new PdfPCell(new Paragraph(p.FellowsResponsibility, cellFont));
                            ResponsibilityCell.Colspan = 1;
                            ResponsibilityCell.Border = PdfPCell.NO_BORDER;
                            table.AddCell(ResponsibilityCell);

                            PdfPCell PartSurCell = new PdfPCell(new Paragraph(p.PartnerSurname, cellFont));
                            PartSurCell.Colspan = 1;
                            PartSurCell.Border = PdfPCell.NO_BORDER;
                            table.AddCell(PartSurCell);

                        }


            pdfDoc.Add(table);

        }
}

2 个答案:

答案 0 :(得分:0)

doc似乎照顾output,如果您关闭doc它会关闭output,因此它不再可用。

您需要重构代码,以便返回doc而不是output并在其他地方管理(处置)。

答案 1 :(得分:0)

我怀疑doc.Close()正在关闭基础流,并根据您的评论,我想知道您是否重置了流的位置。您可以尝试制作流的另一个副本并考虑它的位置。

示例:

protected MemoryStream printSelectionPDF()
{
    var output = new MemoryStream();
    var doc = new Document(PageSize.A4);
    var writer = PdfWriter.GetInstance(doc, output);

    string Sur = DropDownListSurname.SelectedValue;
    string Cat = DropDownListCategory.SelectedItem.Text;
    string Pos = DropDownListPosition.SelectedItem.Text;
    string Resp = DropDownListResp.SelectedValue;

    doc.SetMargins(36, 36, 18, 18);

    GridView1.AllowPaging = false;
    GridView1.DataBind();
    doc.Open();
    CreatePDF(doc, rdBtnStaff.Checked, IncludeHistoricCheckBox.Checked, Sur, Cat, Pos, Resp);

    // copying stream
    output.Flush();
    output.Position = 0;
    var copyStream = new MemoryStream();
    output.CopyTo(copyStream);
    copyStream.Position = 0;
    // end copying stream

    doc.Close();
    GridView1.AllowPaging = true;
    return copyStream;
}