Nick Libee
Nick Libee

Reputation: 1

export arabic data to pdf using itext

I want to export gridview data to PDF, using iTextsharp. The gridview data contains Persian/Arabic data. It results in just a blank PDF file... what could be the reason?

Following is my code:

    GridView1.DataSource = Session("dt")
    GridView1.AllowPaging = False
    GridView1.DataBind()

    Dim bf As BaseFont = BaseFont.CreateFont(Environment.GetEnvironmentVariable("windir") & "\fonts\tahoma.ttf", BaseFont.IDENTITY_H, True)
    Dim font As New iTextSharp.text.Font(bf, 10, iTextSharp.text.Font.NORMAL)
    Dim table As New iTextSharp.text.pdf.PdfPTable(GridView1.Columns.Count)
    Dim widths As Integer() = New Integer(GridView1.Columns.Count - 1) {}
    For x As Integer = 0 To GridView1.Columns.Count - 1
        widths(x) = CInt(GridView1.Columns(x).ItemStyle.Width.Value)
        Dim cellText As String = Server.HtmlDecode(GridView1.HeaderRow.Cells(x).Text)
        Dim cell As New iTextSharp.text.pdf.PdfPCell(New Phrase(12, cellText, font))
        cell.BackgroundColor = New BaseColor(GridView1.HeaderStyle.BackColor)
        'cell.BackgroundColor = New BaseColor(System.Drawing.ColorTranslator.FromHtml("#008000"))
        cell.RunDirection = PdfWriter.RUN_DIRECTION_RTL
        table.AddCell(cell)
    Next
    table.SetWidths(widths)

    For i As Integer = 0 To GridView1.Rows.Count - 1
        If GridView1.Rows(i).RowType = DataControlRowType.DataRow Then
            For j As Integer = 0 To GridView1.Columns.Count - 1
                Dim cellText As String = Server.HtmlDecode(GridView1.Rows(i).Cells(j).Text)
                Dim cell As New iTextSharp.text.pdf.PdfPCell(New Phrase(12, cellText, font))
                'Set Color of Alternating row
                If i Mod 2 <> 0 Then
                    'cell.BackgroundColor = New BaseColor(System.Drawing.ColorTranslator.FromHtml("#C2D69B"))
                    cell.BackgroundColor = New BaseColor(GridView1.RowStyle.BackColor)
                End If
                cell.RunDirection = PdfWriter.RUN_DIRECTION_RTL
                table.AddCell(cell)
            Next
        End If
    Next

    'Create the PDF Document
    Dim pdfDoc As New Document(PageSize.A4, 10.0F, 10.0F, 10.0F, 0.0F)
    PdfWriter.GetInstance(pdfDoc, Response.OutputStream)
    pdfDoc.Open()
    pdfDoc.Add(table)
    pdfDoc.Close()
    Response.ContentType = "application/pdf"
    Response.AddHeader("content-disposition", "attachment;filename=GridViewExport.pdf")
    Response.Cache.SetCacheability(HttpCacheability.NoCache)
    Response.Write(pdfDoc)
    Response.[End]()

Upvotes: 0

Views: 854

Answers (1)

Bruno Lowagie
Bruno Lowagie

Reputation: 77528

Your question is somewhat misleading because the problem you are experiencing is not caused by the fact that you are using Arabic. If you would write the document to a file, you would notice that the file is OK.

There is a serious error in these lines:

PdfWriter.GetInstance(pdfDoc, Response.OutputStream)
...
Response.ContentType = "application/pdf"
Response.AddHeader("content-disposition", "attachment;filename=GridViewExport.pdf")
Response.Cache.SetCacheability(HttpCacheability.NoCache)
Response.Write(pdfDoc)
Response.[End]()

First you use the Response.OutputStream to write PDF bytes to it, then you use the Response object to set content headers. This is illegal syntax: you should always define your headers before sending any bytes to the output stream.

Furtermore: you should write PDF bytes to the outputstream, not a Document object. The following line is complete non sense:

Response.Write(pdfDoc)

For an example on how to send content bytes to the Response.OutputStream, read the answers to the following question: iTextSharp generated PDF: How to send the pdf to the client and add a prompt?

If you don't know how to create content byte, take a look at this code snippet:

using (MemoryStream myMemoryStream = new MemoryStream()) {    
    Document document = new Document();    
    PdfWriter PDFWriter = PdfWriter.GetInstance(document, myMemoryStream);
    document.Open();
    ...
    document.Close();
    byte[] content = myMemoryStream.ToArray();
    ...
}

Never write an object such as document to an output stream, always use a byte[].

Upvotes: 1

Related Questions