Library code snippets
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:
- Copy the file "EmployeeReport" into an ASP.NET web folder.
-
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
\bindirectory to function. - Create a
\bindirectory 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) - Point your browser to your .aspx file, e.g.
http://localhost/... This will create your schema file (Employees.xsd). - 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.
- 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.
- Save your report as "Employees.rpt" in your web folder.
- 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" -->
Related articles
Related discussion
-
how to design a template platform which can be used to create many different pages?
by polytheme (1 replies)
-
Export Datagrid to Excel with same formatting
by saranram_kumar (0 replies)
-
sending sms from pc
by sriraj20074 (0 replies)
-
Capture Video
by ess-image (23 replies)
-
DataGrid - How to display the content of a hidden TemplateField on mouseover
by DonCarnage (0 replies)
Related podcasts
-
StackOverflow uses ASP.NET MVC - Jeff Atwood and his technical team
Scott chats with Jeff Atwood of CodingHorror.com and most recently, StackOverflow.com. Jeff and Joel Spolsky and their technical team have created a new class of application using ASP.NET MVC. What works, what doesn't, and how did it all go down?
Events coming up
-
Jul
13
IKT-Forum für Menschen mit Behinderungen
Linz, Austria
ICT Forum for People with Disabilities.Deutschsprachige Konferenz mit den Themenschwerpunkten: Unterstützte Kommunikation (Technologien, Symbolsysteme, Gebärdensprache, etc.), Barrierefreies Web- und Softwaredesign, Barrierefreies Dokument- un...
I tried implementing the code you posted and I keep receiving a "File or assembly name CrystalKeyCodeLib, or one of its dependencies, was not found." I'm sure it has something to do with the Crystal Reports registration issue in VS.NET. In a normal deployment you would use the proper merge modules to make it work but I can't seem to accomplish that here.
Any help would be appreciated!!
Thanks
I will post here a version of Crystal Reports integrated into Visual Studio.NET
Basically you have to create a Crystal Report using VS.NET (Employees.rpt) and don't worry about "Save report with data Option". This does not exists in VS.NET.
Another thing is to that line dt.tableName = "Table" because the table name is set at the begining of the code (string tableName = "Employees"
I will attach the whole code here:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.IO;
using System.Xml;
using System.Text;
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
namespace CRep
{
/// <summary>
/// Summary description for WebForm1.
/// </summary>
public class WebForm1 : System.Web.UI.Page
{
private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
//* 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 = "Employees";
string rptFile = "Employees.rpt";
string xsdFile = "Employees.xsd";
string pdfFile = "Employees.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();
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("Employees.pdf");
doc.Export();
Response.Write("<a href=\"" + pdfFile + "\">" + pdfFile + "</a>");
}
}
region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
endregion
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 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;
}
}
}
Very good article, but it doesn't discuss the version of Crystal Reports integrated into Visual Studio.NET. How do I turn OFF the "Save Report with Data" option in that environment? I need to get it working. Please, help!
The only code missing that I can see is the functions that retrieved the info from the database - so just replace the line
DataTable dt = qs.GetDataTable("SELECT * FROM fin");
in GetTheData() with your own method for retrieving the data.
Hi
Do you have all the source code available so that I can try the example out
Wayne
This thread is for discussions of How to create PDF files from ASP.NET pages.