格式错误不是pdf或已损坏

时间:2014-05-16 13:03:41

标签: c# asp.net pdf itextsharp

我正在尝试将gridview数据导出为pdf并且正常。但pdf文件显示错误消息 -

enter image description here

代码是 -

protected void Export_to_PDF(object sender, System.EventArgs e)
{
    try
    {
        Response.Clear(); //this clears the Response of any headers or previous output
        Response.Buffer = true; //ma
        Response.ContentType = "application/pdf";

    Response.AddHeader("content-disposition", "attachment;filename=DataTable.pdf");

    Response.Cache.SetCacheability(HttpCacheability.NoCache);

    StringWriter sw = new StringWriter();

    HtmlTextWriter hw = new HtmlTextWriter(sw);

    GridView1.RenderControl(hw);

    StringReader sr = new StringReader(sw.ToString());

    Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 10f, 0f);

    HTMLWorker htmlparser = new HTMLWorker(pdfDoc);

    PdfWriter.GetInstance(pdfDoc, Response.OutputStream);

    pdfDoc.Open();

    htmlparser.Parse(sr);

    pdfDoc.Close();

    Response.Write(pdfDoc);

    Response.End();  


}
catch (Exception ex)
{
    Console.WriteLine("An error occurred: '{0}'", ex);

}

}

我的样本就是这样 -

enter image description here

 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="LoginMaster.aspx.cs" Inherits="QuestionCategories" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Grid View Example............Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div style="height: 316px">
        <asp:Button ID="btnAdd" runat="server" OnClick="btnAdd_Click" Text="New User" /><br />
        <br />
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" CellPadding="4"
            DataKeyNames="UserName" ForeColor="#333333" GridLines="None" OnRowCancelingEdit="GridView1_RowCancelingEdit"
            OnRowDeleting="GridView1_RowDeleting" OnRowEditing="GridView1_RowEditing" 
            OnRowUpdating="GridView1_RowUpdating">
            <FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
            <Columns>
                <asp:CommandField HeaderText="Edit-Update" ShowEditButton="True" />
                <asp:BoundField DataField="UserName" HeaderText="User Name" />
                <asp:BoundField DataField="usergroup" HeaderText="User Group" />
                <asp:CommandField HeaderText="Delete" ShowDeleteButton="True" />
            </Columns>
            <RowStyle BackColor="#FFFBD6" ForeColor="#333333" />
            <SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" />
            <PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" />
            <HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
            <AlternatingRowStyle BackColor="White" />
        </asp:GridView>
        &nbsp;<asp:Button ID="Button1" runat="server" onclick="Export_to_PDF" 
            Text="Export to PDF" Width="156px" />
    </div>
    </form>
</body>
</html>

为什么我收到此错误? 任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

您正在直接写入OutputStream,然后将自定义对象推送到流中。除了重复工作之外,您推送的对象并不像我们想象的那样代表PDF,而是一个内部表示。我将建议一些改变。

首先,在100%确定您拥有有效的PDF之前,请不要修改HTTP响应流。否则,错误消息将以PDF类型发送,并且事情可能会让您感到困惑。其次,与第一个类似,不要将PDF编写器绑定到HTTP响应流,这将使调试更容易。相反,写入MemoryStream并从成功时获取字节。

//Do PDF stuff first

//We'll put our final bytes here when we're done
byte[] bytes;

//Write to a MemoryStream so that we don't pollute the HTTP pipeline
using (var ms = new MemoryStream()) {
    //This is all the same
    StringWriter sw = new StringWriter();
    HtmlTextWriter hw = new HtmlTextWriter(sw);
    GridView1.RenderControl(hw);
    StringReader sr = new StringReader(sw.ToString());
    Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 10f, 0f);
    HTMLWorker htmlparser = new HTMLWorker(pdfDoc);

    //Use our above MemoryStream instead of the OutputStream
    PdfWriter.GetInstance(pdfDoc, ms);

    //Same
    pdfDoc.Open();
    htmlparser.Parse(sr);
    pdfDoc.Close();

    //The above is done, get the byte representation of our PDF
    bytes = ms.ToArray();
}

//If the above works, change the HTTP stream to output the PDF
Response.Clear(); //this clears the Response of any headers or previous output
Response.Buffer = true; //ma
Response.ContentType = "application/pdf";

Response.AddHeader("content-disposition", "attachment;filename=DataTable.pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
//Write our byte array
Response.BinaryWrite(bytes);
Response.End();

修改

如果上述情况不起作用,那么问题就在于以下四行:

StringWriter sw = new StringWriter();
HtmlTextWriter hw = new HtmlTextWriter(sw);
GridView1.RenderControl(hw);
StringReader sr = new StringReader(sw.ToString());

尝试使用以下单行代替上述四项:

StringReader sr = new StringReader("<p>Hello</p>");

如果有效,那么你需要弄清楚你的HTML有什么问题。放弃所有PDF概念并检查sw.ToString()。请记住,iTextSharp对ASP.Net没有任何了解,它只能与HTML一起使用。

如果上面仍然产生了破损的PDF,那么你需要稍微使用Response对象。通过删除缓存和标头来简化它。不要直接打开PDF,而是先将其下载到磁盘。发布PDF链接,我们可以为您提供更多帮助。

此外,HTMLWorker已经很老了,不再维护了。请考虑升级到XmlWorker