Introduction
There are situations in every business where it would be nice to have a PDF that is a combination of Portrait and Landscape printing preferences. One of the key business areas, "Billing," is always attempting to achieve this. This article shows how to create PDFs in the different printing preferences of Landscape and Portrait using the Crystal Report "Export to PDF" function, merging them into one single PDF in ASP.NET. A 3rd party COM component called CutePDF was licensed to merge the PDFs to one final report.
Background
The billing department had a history of creating these bills as printed bills and mailing them to the customers. An idea was tossed around to make these bills available online, but the business users and sponsors insisted that online bills match z to z to the printed bill. Needless to say, an excessive amount of time was spent to achieve this using Crystal Report. To add to the horror, the first page of the printed bill was printed in Portrait and the rest of the pages in Landscape. The research started immediately and the deadline was near, like always, in the IT department.
Using the Code
The first step is to create Crystal reports. First, make the page or the pages in Portrait as one report. Make the other page or pages in Landscape as another report. We are not going to show how to create Crystal reports in this article. I'll work on another article soon. The code block below shows how to programmatically export the data to PDF in portrait settings.
Dim CrReport As ReportDocument
' Report Name to set the printing options
Dim CrPrintOptions As PrintOptions
'set the export options of the report
Dim CrExportOptions As ExportOptions
Dim CrFormatTypeOptions As New PdfRtfWordFormatOptions()
'define the folder to save the reports
Dim CrDiskFileDestinationOptions As DiskFileDestinationOptions
' Localise the filepath and load the report
Dim sPDFName As String = CStr(Now().Millisecond())
Dim sPath As String = "C:\report\"
'first page of the report
Dim sPDFFile1 As String = sPath + sPDFName + "_a.pdf"
'Other Pages report
Dim sPDFFile2 As String = sPath + sPDFName + "_b.pdf"
'the final report name
Dim sPDFFinal As String = sPath + sPDFName + ".pdf"< BR >
CrReport = New ReportDocument()
'load the report
CrReport.Load(reportPath)
CrDiskFileDestinationOptions = New DiskFileDestinationOptions()
'first page report file name is set
CrDiskFileDestinationOptions.DiskFileName = sPDFFile1
' Specify a page range (optional)
CrFormatTypeOptions.FirstPageNumber = 1
' Start Page in the Report
CrFormatTypeOptions.LastPageNumber = 1
' End Page in the Report
CrFormatTypeOptions.UsePageRange = True
' Set export options
CrExportOptions = CrReport.ExportOptions
With CrExportOptions
' Set the destination to a disk file
.ExportDestinationType = ExportDestinationType.DiskFile
' Set the format to PDF
.ExportFormatType = ExportFormatType.PortableDocFormat
' Set the destination options to DiskFileDestinationOptions object
.DestinationOptions = CrDiskFileDestinationOptions
.FormatOptions = CrFormatTypeOptions
End With
'load the dataset
Dim dsHeader As DataSet
CrReport.SetDataSource(dsHeader)
CrPrintOptions = CrReport.PrintOptions
'set the paper orientation to portrait for the first page
With CrPrintOptions
.PaperOrientation = PaperOrientation.Portrait
End With
' Export the report
CrReport.Export()
This code block shows how to programmatically export the data to PDF in Landscape.
With CrPrintOptions
'for multi page reports set the page orientation landscape from 3rd page
.PaperOrientation = PaperOrientation.Landscape
CrFormatTypeOptions.FirstPageNumber = 3
End With
'set the report name for the 2nd pdf file
CrDiskFileDestinationOptions.DiskFileName = sPDFFile2
'set maximum page number for lastPageNumber property because
'it's unknown at the design time
CrFormatTypeOptions.LastPageNumber = 2000
' End Page in the Report
CrFormatTypeOptions.UsePageRange = True
CrReport.Export()
CrReport.Dispose()
Here we show how to merge PDFs into a final report. We use a 3rd party COM component to achieve this, but there are free open source ones to accomplish this as well.
Dim ocutePDF As CutePDFDocument
'create a new instance of CutePDFDocument
ocutePDF = New CutePDFDocument
If System.IO.File.Exists(sPDFFile1) Then
'merge the files to one final report
ocutePDF.mergePDF(sPDFFile1, sPDFFile2, sFinalReport)
End If
Finally, we show how to display the final PDF in a browser.
Dim client As System.IO.FileStream
Dim objFile As System.IO.FileInfo = New System.IO.FileInfo(sFile)
' open the final billing report to read
client = New System.IO.FileStream(sFile, IO.FileMode.Open)
Dim buffer As Byte() = New Byte(CInt(client.Length)) {}
'read the file into byte array
client.Read(buffer, 0, buffer.Length)
Response.Clear()
Response.ClearHeaders()
Response.ContentType = "application/octet-stream"
Response.AppendHeader("Content-Disposition", _
"attachment; filename=" + objFile.Name)
Response.AppendHeader("Expires", "0")
Response.AppendHeader("Content-Description", "File Transfer")
Dim memStream As New IO.MemoryStream(buffer)
memStream.WriteTo(Response.OutputStream)
memStream.Close()
Response.End()
Points of Interest
One more little piece we worked on was to delete the temporary PDF files after creating a final report. This saved hard disk space and made maintenance to support staff less of a headache. Believe me, you want to keep the support staff happy. Happy programming!! And don't forget to have fun.
History
- 14 September, 2007 -- Original version posted