How to create PDF files from ASP.NET pages

Visual Studio .NET comes with a useful version of Crystal Reports which allows you to create Crystal Reports (.rpt files) and then bind them to your database to produce PDF files on a web page, all from within the Visual Studio .NET GUI without ever even getting into the code. As easy as this is, you can have a lot more control over the process if you do it yourself.

This code shows you how to create and bind a DataSet and a Crystal Report file (.rpt) without even using Visual Studio at all (I used Web Matrix). It is assumed, however, that you have access to the Crystal Reports .dlls which came with Visual Studio .NET and that you have the ability to create .rpt files (I used Crystal Reports 9.0).

Here are the steps:

  1. Copy the file "EmployeeReport" into an ASP.NET web folder.
  2. Important: Make SURE that that folder is a WEB folder and not just a sub-directory of another ASP.NET web folder. This is necessary for the \bin directory to function.
  3. Create a \bin directory and copy the two .dll files "CrystalDecisions.CrystalReports.Engine.dll" and "CrystalDecisions.Shared.dll" to your bin directory (I found the .dlls here: C:\Program Files\Common Files\Crystal Decisions\1.1\Managed)
  4. Point your browser to your .aspx file, e.g. http://localhost/... This will create your schema file (Employees.xsd).
  5. In Crystal Reports, create a report from a ADO.NET XML data source. When you are asked for an XML file, point it to your .XSD file. Create the report just as you would any other report from the fields in the table provided.
  6. Important: click on FILE and turn OFF the option "Save Report with Data". This will allow your .rpt file to use information coming from a DataSet at run-time, otherwise it will ignore the DataSet and always be empty.
  7. Save your report as "Employees.rpt" in your web folder.
  8. Now in your .aspx file, change the action variable to "CreatePdf" and reload the page in your browser. You should see a link to "Employees.pdf". Click on it and you will see your PDF file which was created by combining your DataSet with your RPT file. Note that the line "dt.TableName = "Table";" is very important. If you change this name, then you table won't get through to your report. I believe you can rename your table but it has to have the same name when you create the schema as when you run the report.

 

 

<%@ Page Language="C#" Debug="true" %>
<%@ import Namespace="CrystalDecisions.CrystalReports.Engine" %>
<%@ import Namespace="CrystalDecisions.Shared" %>
<%@ import Namespace="System.Data" %>
<%@ import Namespace="System.IO" %>
<%@ import Namespace="System.Xml" %>
<%@ import Namespace="System.Text" %>
<script runat="server">
    public void Page_Load(Object sender, EventArgs E) {
        //*** INSTRUCTIONS:
        //define action for this program
        //1. set action to "CreateSchemaFile"
        //2. run program which creates your .xsd schema file
        //3. create crystal report based on that file
        //4. then set action permanently to "CreatePdf"
        //the command
        string action = "CreatePdf";
        //variables
        string tableName = "fin";
        string rptFile = "fin.rpt";
        string xsdFile = "fin.xml";
        string pdfFile = "fin.pdf";
        //either create the schema (first time only) or the pdf file
        if(action.ToUpper() == "CREATESCHEMAFILE") {
            DataTable dt = new DataTable();
            dt = DummyTable();
            DataSet ds = new DataSet();
            ds.Tables.Add(dt);
            CreateSchemaFile(xsdFile,ds);
            Response.Write("Your schema file has been created:<br/><br/> <b>" + Server.MapPath(xsdFile) + "</b><br/><br/>");
            Response.Write("Use it to create your Crystal Reports report file named:<br/><br/> <b>" + Server.MapPath(pdfFile) + "</b>");
        } else {
            //create the report document
            ReportDocument doc = new ReportDocument();
            string fileName = Server.MapPath(rptFile);
            doc.Load(fileName);
            DataTable dt = DummyTable();
            dt.TableName = tableName;
            DataSet ds = new DataSet();
            dt.TableName    = "Table";
            ds.Tables.Add(dt);
            doc.SetDataSource(ds);
            ExportOptions exportOpts = doc.ExportOptions;
            exportOpts.ExportFormatType = ExportFormatType.PortableDocFormat;
            exportOpts.ExportDestinationType = ExportDestinationType.DiskFile;
            exportOpts.DestinationOptions = new DiskFileDestinationOptions();
            // Set the disk file options.
            DiskFileDestinationOptions diskOpts = new DiskFileDestinationOptions();
            ( ( DiskFileDestinationOptions )doc.ExportOptions.DestinationOptions ).DiskFileName = Server.MapPath("fin.pdf");
            doc.Export();
            Response.Write(dt.Rows.Count);
            Response.Write("<a href=\"" + pdfFile + "\">" + pdfFile + "</a>");
        }

    }
    private void CreateSchemaFile(string fileName, DataSet ds) {
        string absoluteFileName = HttpContext.Current.Server.MapPath(fileName);
        FileStream myFileStream = new FileStream (absoluteFileName, FileMode.Create);
        XmlTextWriter myXmlWriter = new XmlTextWriter(myFileStream, Encoding.Unicode);
        ds.WriteXml( myXmlWriter,XmlWriteMode.WriteSchema );
        myXmlWriter.Close();
    }
    private DataTable GetTheData() {
        //get datatable
        DataTable dt = qs.GetDataTable("SELECT * FROM fin");
        DataTable d2 = dt.Copy();
        return d2;
    }
    private DataTable DummyTable()    {
        //create table
        DataTable dt = new DataTable("Employees");
        dt.Columns.Add("id",Type.GetType("System.Int32"));
        dt.Columns.Add("FirstName",Type.GetType("System.String"));
        dt.Columns.Add("LastName",Type.GetType("System.String"));
        dt.Columns.Add("HireDate",Type.GetType("System.DateTime"));
        //fill rows
        DataRow dr;
        for(int x=1;x<=10;x++) {
            dr = dt.NewRow();
            dr["id"] = x;
            dr["FirstName"] = "Joe" + x;
            dr["LastName"] = "Smith" + x;
            dr["HireDate"] = DateTime.Now;
            dt.Rows.Add(dr);
        }
        return dt;
    }
</script>
<!--#include file="qs.aspx" -->

You might also like...

Comments

Edward Tanguay Edward Tanguay updates his personal web site tanguay.info weekly with code, links, quotes and thoughts on web development. Sign up for the free newsletter.

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“The most exciting phrase to hear in science, the one that heralds new discoveries, is not 'Eureka!' but 'That's funny...'” - Isaac Asimov