locked
create pdf RRS feed

  • Question

  • User1382482195 posted

    i found this useful code:

    01.public override void VerifyRenderingInServerForm(Control control)   
    02.    {   
    03.  
    04.        /* Verifies that the control is rendered */  
    05.  
    06.    }   
    07.  
    08.  
    09.protected void imgbtnpdf_Click(object sender, ImageClickEventArgs e)   
    10.    {   
    11.          
    12.  
    13.        Response.ContentType = "application/pdf";   
    14.  
    15.        Response.AddHeader("content-disposition",   
    16.  
    17.            "attachment;filename=GridViewExport.pdf");   
    18.  
    19.        Response.Cache.SetCacheability(HttpCacheability.NoCache);   
    20.  
    21.        StringWriter sw = new StringWriter();   
    22.  
    23.        HtmlTextWriter hw = new HtmlTextWriter(sw);   
    24.  
    25.        GridView2.AllowPaging = false;   
    26.  
    27.        GridView2.DataBind();   
    28.  
    29.        GridView2.RenderControl(hw);   
    30.  
    31.        StringReader sr = new StringReader(sw.ToString());   
    32.  
    33.        iTextSharp.text.Document pdfDoc = new iTextSharp.text.Document(iTextSharp.text.PageSize.A4, 10f, 10f, 10f, 0f);   
    34.  
    35.        HTMLWorker htmlparser = new HTMLWorker(pdfDoc);   
    36.  
    37.        PdfWriter.GetInstance(pdfDoc, Response.OutputStream);   
    38.  
    39.        pdfDoc.Open();   
    40.  
    41.        htmlparser.Parse(sr);   
    42.  
    43.        pdfDoc.Close();   
    44.  
    45.        Response.Write(pdfDoc);   
    46.  
    47.        Response.End();   
    48.  
    49.  
    


     

    and i'm getting this error  RegisterForEventValidation can only be called during Render();

     

         i cant disable validation method at page drectives, so how can i solve this? where is the bug here?.....i use itextsharp 5.0.5

     

    This will export the gridview with the associated images?

     

    Sunday, February 6, 2011 10:22 AM

All replies

  • User-158764254 posted

    in the click event, set a page level boolean variable to True to indicate that you want to generate a pdf when the page renders.

    then move all the code to generate the pdf out of the click event and into an override of the render event

    if the page level variable is set to True, then run the pdf generation code - else just call the base render method and let the page render normally.

    Sunday, February 6, 2011 10:32 AM
  • User1382482195 posted

    sorry i dont uderstand...

     

    so i move all code to generate the pdf into a function and on the click button event set a bool with true or false if i want tto generate the pdf but how do i say to render the page normally ? 

    Sunday, February 6, 2011 11:05 AM
  • User-158764254 posted

    something like this:

        Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
            If generatepdf = True Then
    
                'pdf generation code called here
    
            Else
    
                'let page render normally
                MyBase.Render(writer)
    
            End If
    
        End Sub


     

    Sunday, February 6, 2011 11:08 AM
  • User1382482195 posted

    i use csgarp so i use this code:

     

    protected override void Render(System.Web.UI.HtmlTextWriter writer)
    {
     if (generatepdf == true) {

     //pdf generation code called here  

     } else {

      //let page render normally  
      base.Render(writer);

     }
    }

    however how can i call it (the render void9 when button is pressed i use button click event but i dont find anyway to call the render void

    Sunday, February 6, 2011 11:29 AM
  • User-158764254 posted

    the framework calls render every time a page is run.  it is not something you need to call directly. 

    Sunday, February 6, 2011 11:32 AM
  • User1382482195 posted

    you dont understand

     

    if i have the code to generate the pdf out of button click event i need to call the

    Protected Overrides Sub Render because its where the code to the pdf is  so i change it to public

     

    public override void Render


    and then i can call the render void however i need to pass in argunment the

     

    HtmlTextWriter writer


    so it will be something like :

     

    protected void imgbtnpdf_Click(object sender, ImageClickEventArgs e)
        {
            generatepdf=true;
            Render(HtmlTextWriter writer);
        }
    


    and the Render(HtmlTestWriter writer is giving me an error its says it is a type and i'm using it like a method 

    Sunday, February 6, 2011 11:47 AM
  • User-158764254 posted

    i do understand ;-)

    Render is a standard page lifecycle method that the framework will call every time the page runs.  we never call render ourselves for the page.

    when your page runs you will get the lifecycle events fired in this order

    Init
    Load
    Click - you set your flag
    PreRender
    Render - you check your flag

    Sunday, February 6, 2011 11:58 AM
  • User1382482195 posted

    please read my edited post above 

    Sunday, February 6, 2011 12:01 PM
  • User-158764254 posted

    when you override Render, the framework will still call the Render method and will thus invoke your override.

    so in the click event you do not need to call render.  you only need to set the flag.

    protected void imgbtnpdf_Click(object sender, ImageClickEventArgs e)     { 
            generatepdf=true; 
            //        Render(HtmlTextWriter writer); // no - dont call render yourself
        } 

    after the click runs and you set your flag, the page lifecycle will continue and the framework will subsequently invoke the Render method.

    at that point, your render override is invoked and your code checks the flag and renders as appropriate.

    Sunday, February 6, 2011 12:10 PM
  • User1382482195 posted

    you are correct i just set the flag!

    however it gives me un error while databing the grid view it says Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control.

    what is teh problem now?!

     

    see code:

     

    bool generatepdf;
    
    
    
        protected void imgbtnpdf_Click(object sender, ImageClickEventArgs e)
        {
            generatepdf=true;
           
        }
    
    
        protected override void Render(HtmlTextWriter writer)
        {
            
    
            if (generatepdf == true)
            {
                Response.ContentType = "application/pdf";
    
                Response.AddHeader("content-disposition",
    
                    "attachment;filename=GridViewExport.pdf");
    
                Response.Cache.SetCacheability(HttpCacheability.NoCache);
    
                StringWriter sw = new StringWriter();
    
                HtmlTextWriter hw = new HtmlTextWriter(sw);
    
                GridView2.AllowPaging = false;
    
                GridView2.DataBind();
    
                GridView2.RenderControl(hw);
    
                StringReader sr = new StringReader(sw.ToString());
    
                iTextSharp.text.Document pdfDoc = new iTextSharp.text.Document(iTextSharp.text.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();
    
                //pdf generation code called here   
    
            }
            else
            {
    
                //let page render normally   
                base.Render(writer);
    
            }
        }
    
    


     edit: since the gridview is already binded i take ou the line gridview2.databind();

    then i get this error:

     

    Control 'ctl00_MainContent_GridView2' of type 'GridView' must be placed inside a form tag with runat=server.

     i use a template filed could this be a problem because run at server tag is there....

    see code:

     

    asp:GridView ID="GridView2" runat="server" AllowPaging="True" 
            AllowSorting="True" AutoGenerateColumns="False" CellPadding="4" 
            DataKeyNames="IDTipo" DataSourceID="GestaoCategorias" ForeColor="#333333" 
            GridLines="None" Width="400px" HorizontalAlign="Center">
            <RowStyle BackColor="#EFF3FB" />


     

    Sunday, February 6, 2011 12:18 PM
  • User1382482195 posted

    due to old code of itextsharp version that i have used i have to change the code (now supports 5.0.5)

     

    so new code is like this 

     

     public override void VerifyRenderingInServerForm(Control control)
        {
    
            /* Verifies that the control is rendered */ 
            /* Necessario para gerar pdf com gridview */
    
        }
    
    
    
    
    
        bool gerarpdf;
    
    
        protected void imgbtnpdf_Click(object sender, ImageClickEventArgs e)
        {
            gerarpdf=true;
           
            
        }
    
    
    
    
        protected override void Render(HtmlTextWriter writer)
        {
    
         
            if (gerarpdf == true)
            {
              
                //pdf generation code called here  
    
                 
    
        int columns = GridView2.Columns.Count;
    // Table and PdfTable classes removed in version 5.XXX
        iTextSharp.text.pdf.PdfPTable table = new iTextSharp.text.pdf.PdfPTable(columns);
    // padding can only be set for cells, __NOT__ PdfPTable object
        int padding = 5;
        float[] widths = new float[columns];
        for (int x = 0; x < columns; x++) {
          widths[x] = (float) GridView2.Columns[x].ItemStyle.Width.Value;
          string cellText = Server.HtmlDecode(GridView2.HeaderRow.Cells[x].Text);
    // Cell and Color classes are gone too      
          iTextSharp.text.pdf.PdfPCell cell = new iTextSharp.text.pdf.PdfPCell(new iTextSharp.text.Phrase(cellText))
          {
              BackgroundColor = new iTextSharp.text.BaseColor(
              System.Drawing.ColorTranslator.FromHtml("#008000")
            ),
            Padding = padding
          };
          table.AddCell(cell);
        }
    // next two lines set the table's __ABSOLUTE__ width     
        table.SetTotalWidth(widths);
        table.LockedWidth = true;
    
        for (int i = 0; i < columns; i++) {
          if (GridView2.Rows[i].RowType == DataControlRowType.DataRow) {
            for (int j = 0; j < columns; j++) {
              string cellText = Server.HtmlDecode(GridView2.Rows[i].Cells[j].Text);
              iTextSharp.text.pdf.PdfPCell cell = new iTextSharp.text.pdf.PdfPCell(new iTextSharp.text.Phrase(cellText))
              {
                Padding = padding
              };
              if (i % 2 != 0) {
                  cell.BackgroundColor = new iTextSharp.text.BaseColor(
                  System.Drawing.ColorTranslator.FromHtml("#C2D69B")
                );
              }
              table.AddCell(cell);
            }
          }
        }
        Response.ContentType = "application/pdf";
        iTextSharp.text.Document pdfDoc = new iTextSharp.text.Document(iTextSharp.text.PageSize.A4, 10f, 10f, 10f, 0f);
        iTextSharp.text.pdf.PdfWriter.GetInstance(pdfDoc, Response.OutputStream);
        pdfDoc.Open();
        pdfDoc.Add(table);
        pdfDoc.Close(); 
        Response.End();  
      }
    
            
            else
            {
    
                //let page render normally   
                base.Render(writer);
    
            }
        }


     

    then i getting this error:

    The table width must be greater than zero.

    i need to bind the gridview but i dont know where to put the code

     

    Sunday, February 6, 2011 2:56 PM
  • User-158764254 posted

    The table width must be greater than zero.

    It might be that your pdf component wants the grid to have an explicit width.

    try assigning the GridView a width in the markup.  something like this maybe.

        <asp:Gridview ...  Width="400px" ...

    Sunday, February 6, 2011 3:06 PM
  • User1382482195 posted

    after trying ur suggestion still the same

    i think i nee to bind the gridview but i dont know where to put it  

    Sunday, February 6, 2011 3:28 PM
  • User-158764254 posted

    in your earlier code i see you are calling databind on the gridview in the override of Render.

    make sure you're also setting the DataSource of the GridView before you call databind - otherwise databinding with an empty datasource will result in no rows of data.

    Sunday, February 6, 2011 3:31 PM
  • User1382482195 posted

    in your earlier code i see you are calling databind on the gridview in the override of Render.

    make sure you're also setting the DataSource of the GridView before you call databind - otherwise databinding with an empty datasource will result in no rows of data.

     

    if i do that i get this mesage: Both DataSource and DataSourceID are defined on 'GridView2'.  Remove one definition.

     

    see code:

     

    //pdf generation code called here  
    
                GridView2.DataSource = GestaoArtigos;
                GridView2.DataBind();  
        int columns = GridView2.Columns.Count;


     i think the problem is because gridview as a datasource id so do not need datasource so i take out data source however then i get this message:

     

    Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control.

    Sunday, February 6, 2011 3:37 PM
  • User1382482195 posted

    the problem is that i need to set a width in itemstyle so i do that and i get the pdf but its appearing like that:

    why is it appearing like that?

     

     

    Monday, February 7, 2011 1:49 PM
  • User1382482195 posted

    no one can help me on this?


    Tuesday, February 8, 2011 4:50 AM
  • User1382482195 posted

    still getting the formating style of gridview no data i have set itemstyle width no nomore errors but i dont have any data in the pdf just the formatting as an image that i show on previous post

    Wednesday, February 16, 2011 11:50 AM
  • User1382482195 posted

    so no one can help me on this?

    Tuesday, February 22, 2011 4:23 PM
  • User82239924 posted

    Try this code.

    GridView GridView1 = new GridView();
            GridView1.AllowPaging = false;
            GridView1.DataSource = dsPDF;
            GridView1.DataBind();
            HtmlForm form = new HtmlForm();
            Response.ContentType = "application/pdf";
            Response.AddHeader("content-disposition", "attachment;filename=Task-List.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();
    Wednesday, July 6, 2011 1:42 AM