EXPORT PDF from VB.NET
-
This is similar to an earlier post, but different enough I think for a new one. I have tried a few things I've found online, but none have worked. I am loading a template for a CrystalReport, then filling it, then I want to export it as a PDF, or RDF, I don't really care right now, but PDF would be preferred. Below is the best I can come up with, but the errors never cease. If anyone has any examples where they did anything like this successfully, that would be great. Thank You! Dim cr As New ReportDocument() cr.Load("path to CrystalReport template .rpt") Dim PKCalls As DataTable = DirectCast(Session("GetPKCallS"), DataTable) PKCalls = New DataTable() Dim sc As New PK.BusinessLogicLayer.Consumer() Dim tDay As Integer Dim tCall As Integer Dim DD As String Dim CallActivity As String tDay = Integer.Parse(txtPast.Text) tCall = Integer.Parse(txtCall.Text) DD = Today.AddDays(-tDay) CallActivity = Today.AddDays(-tCall) PKCalls = sc.GetPKCallSheet(txtGender.Text, txtRace.Text, lblUpDOB.Text, lblLowDOB.Text, ddlSite.SelectedItem.Value, DD, CallActivity) Session("GetPKCallS") = PKCalls Dim ds As New DataSet() ds.Tables.Add(Session("GetPKCallS")) cr.SetDataSource(ds) Dim exportOpts As New ExportOptions() exportOpts.ExportFormatType = ExportFormatType.PortableDocFormat exportOpts.ExportDestinationType = ExportDestinationType.DiskFile exportOpts.DestinationOptions = New DiskFileDestinationOptions() Dim diskOpts As New DiskFileDestinationOptions() Dim N As String N = "CallSheets" & Session("userOffice") & Now & ".PDF" N = Replace(N, Chr(32), "") N = Replace(N, ":", "") N = Replace(N, "/", "") diskOpts = CType(exportOpts.DestinationOptions, DiskFileDestinationOptions) diskOpts.DiskFileName = "path to final destination" & N cr.Export()
can you please post the error that you are receiving?
-jim
-
can you please post the error that you are receiving?
-jim
The error reads "Invalid report file path." And is thrown by: CrystalReportDocument.SetDataSource(ds) Other than that, I can load the template.rpt and send it as a PDF to it's location, I just can't populate the .rpt now. Below is the updated code: Dim PKCalls As DataTable = DirectCast(Session("GetPKCallS"), DataTable) PKCalls = New DataTable() Dim sc As New PK.BusinessLogicLayer.Consumer() Dim tDay As Integer Dim tCall As Integer Dim DD As String Dim CallActivity As String tDay = Integer.Parse(txtPast.Text) tCall = Integer.Parse(txtCall.Text) DD = Today.AddDays(-tDay) CallActivity = Today.AddDays(-tCall) PKCalls = sc.GetPKCallSheet(txtGender.Text, txtRace.Text, lblUpDOB.Text, lblLowDOB.Text, ddlSite.SelectedItem.Value, DD, CallActivity) Session("GetPKCallS") = PKCalls Dim ds As New DataSet() ds.Tables.Add(Session("GetPKCallS")) Dim N As String N = "CallSheets" & Session("userOffice") & Now & ".PDF" N = Replace(N, Chr(32), "") N = Replace(N, ":", "") N = Replace(N, "/", "") Dim CrystalReportDocument As ReportDocument Dim CrystalExportOptions As ExportOptions Dim CrystalDiskFileDestinationOptions As DiskFileDestinationOptions Dim Filename As String CrystalReportDocument = New ReportDocument() CrystalReportDocument.SetDataSource(ds) CrystalReportDocument.Load("path to .rpt") Filename = "destination path" & N CrystalDiskFileDestinationOptions = New DiskFileDestinationOptions() CrystalDiskFileDestinationOptions.DiskFileName = Filename CrystalExportOptions = CrystalReportDocument.ExportOptions With CrystalExportOptions .DestinationOptions = CrystalDiskFileDestinationOptions .ExportDestinationType = ExportDestinationType.DiskFile .ExportFormatType = ExportFormatType.PortableDocFormat End With CrystalReportDocument.Export() Thank you for your help!
-
The error reads "Invalid report file path." And is thrown by: CrystalReportDocument.SetDataSource(ds) Other than that, I can load the template.rpt and send it as a PDF to it's location, I just can't populate the .rpt now. Below is the updated code: Dim PKCalls As DataTable = DirectCast(Session("GetPKCallS"), DataTable) PKCalls = New DataTable() Dim sc As New PK.BusinessLogicLayer.Consumer() Dim tDay As Integer Dim tCall As Integer Dim DD As String Dim CallActivity As String tDay = Integer.Parse(txtPast.Text) tCall = Integer.Parse(txtCall.Text) DD = Today.AddDays(-tDay) CallActivity = Today.AddDays(-tCall) PKCalls = sc.GetPKCallSheet(txtGender.Text, txtRace.Text, lblUpDOB.Text, lblLowDOB.Text, ddlSite.SelectedItem.Value, DD, CallActivity) Session("GetPKCallS") = PKCalls Dim ds As New DataSet() ds.Tables.Add(Session("GetPKCallS")) Dim N As String N = "CallSheets" & Session("userOffice") & Now & ".PDF" N = Replace(N, Chr(32), "") N = Replace(N, ":", "") N = Replace(N, "/", "") Dim CrystalReportDocument As ReportDocument Dim CrystalExportOptions As ExportOptions Dim CrystalDiskFileDestinationOptions As DiskFileDestinationOptions Dim Filename As String CrystalReportDocument = New ReportDocument() CrystalReportDocument.SetDataSource(ds) CrystalReportDocument.Load("path to .rpt") Filename = "destination path" & N CrystalDiskFileDestinationOptions = New DiskFileDestinationOptions() CrystalDiskFileDestinationOptions.DiskFileName = Filename CrystalExportOptions = CrystalReportDocument.ExportOptions With CrystalExportOptions .DestinationOptions = CrystalDiskFileDestinationOptions .ExportDestinationType = ExportDestinationType.DiskFile .ExportFormatType = ExportFormatType.PortableDocFormat End With CrystalReportDocument.Export() Thank you for your help!
try loading the report template before you set the datasource of the reportdocument object. this way the report document object is able to validate the schema of the passed dataset against the templates data definition as the datasource is set. i would think that this would solve your problem. the invalid report file path error is probably being thrown up because of some validation in the setdatasource procedure that's checking to ensure that you've loaded a template first. hope this helps. :)
-jim
-
try loading the report template before you set the datasource of the reportdocument object. this way the report document object is able to validate the schema of the passed dataset against the templates data definition as the datasource is set. i would think that this would solve your problem. the invalid report file path error is probably being thrown up because of some validation in the setdatasource procedure that's checking to ensure that you've loaded a template first. hope this helps. :)
-jim
I put "CrystalReportDocument.SetDataSource(ds)" after the load statement. This did stop the error, there are no errors now, however, the Crystal Report is not being filled. I've checked to make sure that the data Table is getting data. Am I setting the data Source from the data Table correctly? Any ideas? I (obviously) haven't done this before. Thank you for your continuing help!
-
I put "CrystalReportDocument.SetDataSource(ds)" after the load statement. This did stop the error, there are no errors now, however, the Crystal Report is not being filled. I've checked to make sure that the data Table is getting data. Am I setting the data Source from the data Table correctly? Any ideas? I (obviously) haven't done this before. Thank you for your continuing help!
no problem! i would then check that your data definition is done correctly. i.e. what did you use to define your data structure to your report template? i typically generate an .xsd file using: myDataset.WriteXML("outputfilename.xsd", xmlwritemode.writeschema) then create the report template using this .xsd file. how are you doing it?
-jim
-
no problem! i would then check that your data definition is done correctly. i.e. what did you use to define your data structure to your report template? i typically generate an .xsd file using: myDataset.WriteXML("outputfilename.xsd", xmlwritemode.writeschema) then create the report template using this .xsd file. how are you doing it?
-jim
I guess I'm missing something big here. I'm used to data grids where you just give it the source and it populates it. Another person made a CrystalReport.rpt file for me to use as a template, that's what I load. Then I have a stored procedure that fills the datatable you see in the code. I didn't know I needed to make a template to pass to the .rpt template. How is something like this done?
-
I guess I'm missing something big here. I'm used to data grids where you just give it the source and it populates it. Another person made a CrystalReport.rpt file for me to use as a template, that's what I load. Then I have a stored procedure that fills the datatable you see in the code. I didn't know I needed to make a template to pass to the .rpt template. How is something like this done?
partt wrote: I didn't know I needed to make a template to pass to the .rpt template if someone already made you a template file, what did they use to define the data definition of that template? that's the key... the underlying datasource (your dataset) needs to match the datadefinition of the report template file. you have 9/10's of the work done really. here's basically step for step what you need to do. from the beginning: 1. decide on your data structure. whatever suits your needs for what you need to display to your user should do. 2. create the dataset either through code or through the xml designer in the vs.net ide. 3. either way you need to end up with a valid .xsd file. (if you create your dataset through code then just step through the code to the point where it's populated and use the command window to perform a myDataset.WriteXml("outputfile.xsd", xmlwritemode.writeschema)) this will give you a file that you can then use to set the datadefinion of your cr template file. 4. Create a new crystal report template (or just open up the one that you already have) and set the datasource for the template = you newly generated .xsd file. 5. Create your report by dragging and dropping fields from your datasource onto the designer. 6. basically do what you did in your code above to load this report template into a reportdocument object and set the datasource = your dataset. it's really not complicated. the most important thing is to make sure that the data structure that you are passing into the reportdocument object as the datasource matches what is defined in the report template. if you have to make some changes to the datasource to add or remove a field, make sure you re-load the data structure back into the report template by right clicking the datasource node in the field explorer and clicking verify database. if they are off slightly you'll get some really generic errors such as 'report load failed', or 'query engine error'. such is life with crystal. i hope this explains the process a little more clearly. if not you know where to find me... :)
-jim
-
partt wrote: I didn't know I needed to make a template to pass to the .rpt template if someone already made you a template file, what did they use to define the data definition of that template? that's the key... the underlying datasource (your dataset) needs to match the datadefinition of the report template file. you have 9/10's of the work done really. here's basically step for step what you need to do. from the beginning: 1. decide on your data structure. whatever suits your needs for what you need to display to your user should do. 2. create the dataset either through code or through the xml designer in the vs.net ide. 3. either way you need to end up with a valid .xsd file. (if you create your dataset through code then just step through the code to the point where it's populated and use the command window to perform a myDataset.WriteXml("outputfile.xsd", xmlwritemode.writeschema)) this will give you a file that you can then use to set the datadefinion of your cr template file. 4. Create a new crystal report template (or just open up the one that you already have) and set the datasource for the template = you newly generated .xsd file. 5. Create your report by dragging and dropping fields from your datasource onto the designer. 6. basically do what you did in your code above to load this report template into a reportdocument object and set the datasource = your dataset. it's really not complicated. the most important thing is to make sure that the data structure that you are passing into the reportdocument object as the datasource matches what is defined in the report template. if you have to make some changes to the datasource to add or remove a field, make sure you re-load the data structure back into the report template by right clicking the datasource node in the field explorer and clicking verify database. if they are off slightly you'll get some really generic errors such as 'report load failed', or 'query engine error'. such is life with crystal. i hope this explains the process a little more clearly. if not you know where to find me... :)
-jim
I talked to the person who made the .rpt file. They told CrystalReports to expect data from the stored procedure I use and they clicked and dragged the field names onto the crystal report sheet from crystal reports' view of that stored procedure. Not sure how clear that was....
-
I talked to the person who made the .rpt file. They told CrystalReports to expect data from the stored procedure I use and they clicked and dragged the field names onto the crystal report sheet from crystal reports' view of that stored procedure. Not sure how clear that was....
yep. perfectly clear. if that's the case, then i believe all you have to do is display the report. once you do that the report should connect to the sproc automatically and pull the data appropriately. i think what you were doing before to keep this from happening was setting the data source. skip this part and let me know if this doesn't work. if your report and/or the stored procedure requires any parameters then you'll need to supply those via code. this isn't that difficult to figure out though. another good source for crystal stuff is brian bischoff's free ebook. it's an abridged version of a book he's since had published regarding crystal reports and .net. it requires registration though. anyways, hope this works out for you.
-jim
-
yep. perfectly clear. if that's the case, then i believe all you have to do is display the report. once you do that the report should connect to the sproc automatically and pull the data appropriately. i think what you were doing before to keep this from happening was setting the data source. skip this part and let me know if this doesn't work. if your report and/or the stored procedure requires any parameters then you'll need to supply those via code. this isn't that difficult to figure out though. another good source for crystal stuff is brian bischoff's free ebook. it's an abridged version of a book he's since had published regarding crystal reports and .net. it requires registration though. anyways, hope this works out for you.
-jim
I tried this but it gives me an error: "Invalid Field Name" Dim crReportDocument As ReportDocument Dim crExportOptions As ExportOptions Dim crDiskFileDestinationOptions As DiskFileDestinationOptions Dim Fname As String crReportDocument = New ReportDocument() crReportDocument.Load("destination to .rpt") Dim logonInfo As New TableLogOnInfo() Dim i As Integer For i = 0 To crReportDocument.Database.Tables.Count - 1 logonInfo.ConnectionInfo.ServerName = "servername" logonInfo.ConnectionInfo.DatabaseName = "DBname" logonInfo.ConnectionInfo.UserID = "userID" logonInfo.ConnectionInfo.Password = "passWord" crReportDocument.Database.Tables.Item(i).ApplyLogOnInfo(logonInfo) Next Dim discreteParam As New ParameterDiscreteValue() Dim paramField As ParameterFieldDefinition Dim defaultValue As ParameterValues paramField = crReportDocument.DataDefinition.ParameterFields.Item("SexID") discreteParam.Value = txtGender.Text.Trim defaultValue = paramField.DefaultValues defaultValue.Add(discreteParam) paramField.ApplyCurrentValues(defaultValue) paramField = crReportDocument.DataDefinition.ParameterFields.Item("RaceID") discreteParam.Value = txtRace.Text.Trim defaultValue = paramField.DefaultValues defaultValue.Add(discreteParam) paramField.ApplyCurrentValues(defaultValue) paramField = crReportDocument.DataDefinition.ParameterFields.Item("LBirth") discreteParam.Value = lblUpDOB.Text defaultValue = paramField.DefaultValues defaultValue.Add(discreteParam) paramField.ApplyCurrentValues(defaultValue) paramField = crReportDocument.DataDefinition.ParameterFields.Item("UBirth") discreteParam.Value = lblLowDOB.Text defaultValue = paramField.DefaultValues defaultValue.Add(discreteParam) paramField.ApplyCurrentValues(defaultValue) paramField = crReportDocument.DataDefinition.ParameterFields.Item("SiteID") discreteParam.Value = ddlSite.SelectedItem.Value defaultValue = paramField.DefaultValues defaultValue.Add(discreteParam) paramField.ApplyCurrentValues(defaultValue) Dim tDay As Integer Dim tCall As Integer Dim DD As DateTime 'Date that is X amount of days in the past decided by txtPast Dim CallActi