Create PDF files on-the-fly in ASP.NET (Using Crystal Report!)
Here is another requirement (perhaps a common requirement!) I needed to implement
in one of on-going project website application. I needed to generate a PDF file
as output from the inputs entered by end-user in a form. On Completing the form,
end-user should be able to download a PDF file of what they have given the inputs
in the form.
I need to generate PDF file in a given format and force the download dialog to let
the user save generated PDF save on their/client machine.
I tried searching any free :) third party dlls which would help me to generate PDF
files on-the-fly. Things I tried:
[1] Tried searching almost third party tools/dlls
including
Siberix PDF Library
,
PDF Vision .Net etc etc, which are having similar functionality. But not FREE
:(
[2] Tried with
iTextSharp - Tutorial
and
PDFsharp - Download PDFsharp Version 1.20 These dlls/libraries are totally free
and really interesting to work with. All we need to do is define elements like HTML
and add those elements to PDF document object which then finally generated as PDF
document. But, this is the problem for me as I am having a huge PDF file needed
to generate as output and it would required a loot of time to code for a document
by placing line by line cells, TR and TD, Tables and background, Border colors,
images etc. and most of all is annoying Texts to be placed in those elements with
proper fonts, colors and padding/alignment.
At last after wasting time in googling and
on free tools/libraries, I got an idea to create PDF on-the-fly. I was thinking
of creating PDF files dynamically and I created it smoothly with out too much work
and code.
This is how it goes:
[1] I created a clean A4 size SnapShot of
the PDF file I needed to be generated dynamically.
[2] Next, I added a blank crystal report
to the solution.
[3] I added/set the PDF SnapShot as the background
of the crystal report by Right Click on the detail section of the crystal report
> Insert > Picture > and select the SnapShot and place it inside the detail
section with proper left-top padding.

[4] as of now, Crystal Report is showing
exactly same as the PDF file with blank inputs.
[5] next is, to accept inputs from end-user
and pass those inputs as parameters to Crystal Report.
[6 ] I declared required parameters those
are needed to pass runtime with the input values entered by end-user to Crystal
Report. And place those parameters object in the Crystal Report accurately in a
way, like those parameters were showing as the resultant values in PDF files. At
this time, Crystal Report is having PDF like look with parameters. For this I need to set the PDF SnapShot background "send to BACK" as:

Below are the declared parameters which will be passed dynamically after accepting/submitting user inputs.

This is how Crystal Report saw when Parameters placed on the Crystal Report Detailed section after moving the SnapShot to move BACK:

[7] After Declaring parameters, only thing
left is to pass values and directly export the Crystal Report in PDF file rather
than to show it on user screen. And after successful Export in PDF file, force download
dialog to let end-user save the generated PDF file.
Below is the Code to pass parameters dynamically
and force download dialog to save the file:
'create
the report document
Dim doc
As
New ReportDocument()
Dim fileName
As
String
= Server.MapPath("~/DesktopModules/OnlineForm/OnlineForm.rpt")
'load the rpt
file to document
doc.Load(fileName)
'pass the user
inputs to crystal report parameters those will sit in the output pdf file
doc.SetParameterValue("@CompanyName", txtCompany.Text.Trim())
doc.SetParameterValue("@CustomerName", txtFirstName.Text.Trim()
+
" "
+ txtLastName.Text.Trim())
doc.SetParameterValue("@Address", txtAddress.Text.Trim())
doc.SetParameterValue("@City", txtCity.Text.Trim())
doc.SetParameterValue("@Province", txtProvince.Text.Trim())
doc.SetParameterValue("@PostalCode", txtPostalCode.Text.Trim())
doc.SetParameterValue("@Phone1", txtPhone11.Text.Trim()
+
" - "
+ txtPhone12.Text.Trim() + " - " + txtPhone13.Text.Trim())
doc.SetParameterValue("@Phone2", txtPhone21.Text.Trim()
+
" - "
+ txtPhone22.Text.Trim() + " - " + txtPhone23.Text.Trim())
doc.SetParameterValue("@Phone3", txtPhone31.Text.Trim()
+
" - "
+ txtPhone32.Text.Trim() + " - " + txtPhone33.Text.Trim())
'set the export
options to PDF
Dim exportOpts
As
ExportOptions = doc.ExportOptions
exportOpts.ExportFormatType = ExportFormatType.PortableDocFormat
exportOpts.ExportDestinationType = ExportDestinationType.DiskFile
exportOpts.DestinationOptions =
New DiskFileDestinationOptions()
' Set the disk
file options.
Dim diskOpts
As
New
DiskFileDestinationOptions()
CType(doc.ExportOptions.DestinationOptions,
DiskFileDestinationOptions).DiskFileName = Server.MapPath("~/DesktopModules/OnlineForm/OnlineForm.pdf")
'export the report
to PDF rather than displaying the report in a viewer
doc.Export()
'force download
dialog to download the PDF file at user end.
'Set the appropriate
ContentType.
Response.ContentType = "Application/pdf"
'Get the physical
path to the file.
Dim FilePath
As
String
= Server.MapPath("~/DesktopModules/OnlineForm/OnlineForm.pdf")
'Write the file
directly to the HTTP content output stream.
Response.WriteFile(FilePath)
Response.End()
Thats it!
Hope it would help anybody who need to develop similar functionality!
UPDATE:
incase, if anybody needs code in C#:
//create the report document
ReportDocument doc = new ReportDocument();
string fileName = Server.MapPath("~/DesktopModules/OnlineForm/OnlineForm.rpt");
//load the rpt file to document
doc.Load(fileName);
//pass the user inputs to crystal report parameters those will sit in the output pdf file
doc.SetParameterValue("@CompanyName", txtCompany.Text.Trim());
doc.SetParameterValue("@CustomerName", txtFirstName.Text.Trim() + " " + txtLastName.Text.Trim());
doc.SetParameterValue("@Address", txtAddress.Text.Trim());
doc.SetParameterValue("@City", txtCity.Text.Trim());
doc.SetParameterValue("@Province", txtProvince.Text.Trim());
doc.SetParameterValue("@PostalCode", txtPostalCode.Text.Trim());
doc.SetParameterValue("@Phone1", txtPhone11.Text.Trim() + " - " + txtPhone12.Text.Trim() + " - " + txtPhone13.Text.Trim());
doc.SetParameterValue("@Phone2", txtPhone21.Text.Trim() + " - " + txtPhone22.Text.Trim() + " - " + txtPhone23.Text.Trim());
doc.SetParameterValue("@Phone3", txtPhone31.Text.Trim() + " - " + txtPhone32.Text.Trim() + " - " + txtPhone33.Text.Trim());
//set the export options to PDF
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("~/DesktopModules/OnlineForm/OnlineForm.pdf");
//export the report to PDF rather than displaying the report in a viewer
doc.Export();
//force download dialog to download the PDF file at user end.
//Set the appropriate ContentType.
Response.ContentType = "Application/pdf";
//Get the physical path to the file.
string FilePath = Server.MapPath("~/DesktopModules/OnlineForm/OnlineForm.pdf");
//Write the file directly to the HTTP content output stream.
Response.WriteFile(FilePath);
Response.End();