I have a service that renders a report from SSRS which works perfectly fine with one page, however when I tried to change the code to render multiple pages separately I can't seem to get it to work as expected.
I used a guide on the MSDN blogs (http://blogs.msdn.com/b/bryanke/archive/2004/02/11/71491.aspx#code) to try and achieve this, but my StreamIDs doesn't seem to be working as I expected.
Here's my code from the Render() method onwards (the rest seems to be okay, but I can provide on request):
var firstPage = rsExec.Render(format.ToString(), deviceInfo,
out extension, out encoding,
out mimeType, out warnings, out streamIDs);
var numberOfPages = streamIDs.Length + 1;
results = new Byte[numberOfPages][];
results[0] = firstPage;
if (numberOfPages > 1)
{
for (int i = 1; i < numberOfPages; i++)
{
deviceInfo = $#"
<DeviceInfo>
<OutputFormat>JPEG</OutputFormat>
<StartPage>{i + 1}</StartPage>
</DeviceInfo>";
results[i] = rsExec.Render(format.ToString(), deviceInfo,
out extension, out encoding,
out mimeType, out warnings, out streamIDs);
}
}
This generates the report okay, but I expected the streamIDs to become the number of extra pages required, but it always only has one entry in it. Am I doing something stupidly wrong here?
I'm using SQL Server 2008 R2.
Related
I´m facing this issue a long time, after months i´m still not able to find any solution. Here´s the scenario:
VS 2019, Framework 4.6 and Crystal reports 13_0_27.
The following code takes hours to export a pdf (about 400 pages and 30.000 rows) . If i open the report
with crystal reports and export the document, same query by code, only takes seconds.
I tried a couple things, like ExportToStream and save the stream to file, or exporting direcly to disk
and other post did read that "pdfFormatOptions.UsePageRange = True" should help, but same result.
The code works fine with smalls pdfs with, for example, 100 rows.
Informe.Load(Application.StartupPath + #"\informes\report.rpt");
for (i = 0; i < Informe.Database.Tables.Count; ++i)
{
logOnInfo.ConnectionInfo.ServerName = "Server";
logOnInfo.ConnectionInfo.DatabaseName = "BBDD";
logOnInfo.ConnectionInfo.UserID = "user";
logOnInfo.ConnectionInfo.Password = "user";
Informe.Database.Tables[i].ApplyLogOnInfo(logOnInfo);
}
diskOpts.DiskFileName = PDFPath + _cabe.Guid + "_minutos.pdf";
ExportOptions exportOpts2 = Informe.ExportOptions;
exportOpts2.DestinationOptions = diskOpts;
exportOpts2.ExportFormatType = ExportFormatType.PortableDocFormat;
exportOpts2.ExportDestinationType = ExportDestinationType.DiskFile;
try
{
Informe.RecordSelectionFormula = #" {CabeceraFacturas.Guid}='{" + _cabe.Guid.ToString() + "}'";
//Informe.Export();
Stream oStream;
oStream = (Stream)Informe.ExportToStream(ExportFormatType.PortableDocFormat);
using (FileStream fileStream = File.Create(RutaGeneracionPDF + _cabe.Guid + "_minutos.pdf", (int)oStream.Length))
{
byte[] bytesInStream = new byte[oStream.Length];
oStream.Read(bytesInStream, 0, bytesInStream.Length);
fileStream.Write(bytesInStream, 0, bytesInStream.Length);
fileStream.Close();
}
}
Thanks!
After expending days and hours and headaches i finally did the trick.
in each detail (About 30.000 rows) i had a formula wich calculated some value with two fields of the detail and two from a joined view. the view was the problem when i was exporting by code (Exporting within Crystal Reports worked ok with no delay). I had to create a new table in SQL, inserting all the rows in view in this new table and add this table to report and ..voilá, it worked, exported report in seconds.
So, here's my delema.
The title says it all. I cannot seem to find any guidance on how to execute a SSRS report remotely and save it as a PDF.
I have tried to follow the below article.
Using Reporting Services (SSRS) as a reference in an ASP.NET Core site
However, when I add the Service Reference to my project some of the methods seem to have the wrong signatures.
For example.
rsExec.LoadReportAsync(report, null);
in my reference the first parameter is a TrustedUserHeader object.
Does anyone have a good starting point on how to execute an SSRS report from C#? I cannot find any simple example.
I do this by using Microsoft.Reporting.Webforms and the following method:
using Microsoft.Reporting.WebForms;
...
public byte[] ExportToExcel(string reportName, string[] paramNames, string[][] paramDic)
{
// Variables
Warning[] warnings;
string[] streamIds;
string mimeType;
string encoding;
string extension;
ReportViewer rv = new ReportViewer { ProcessingMode = ProcessingMode.Remote };
rv.AsyncRendering = false;
ServerReport sr = rv.ServerReport;
sr.ReportServerUrl = new Uri("http://<server>/reportserver");
sr.ReportPath = "/<report path>/" + reportName;
if (paramNames.Length != 0)
{
List<ReportParameter> paramList = paramNames.Select((t, i) => new ReportParameter(t, paramDic[i])).ToList();
rv.ServerReport.SetParameters(paramList);
}
return rv.ServerReport.Render("Excel", null, out mimeType, out encoding, out extension,
out streamIds, out warnings);
}
The byte array can then be sent to the client via Response or saved to a file to be emailed/transferred later.
The first parameter is the name of the report, the second is an array of parameter names, and the third is an array of arrays containing the parameter values. I wrote this method early in my career and I wouldn't write it this way now. If you use this, I would refactor the code to take two parameters: reportName and a Dictionary called parameters or something like that to manage the parameter values.
I would like to somehow cycle through my Reporting Server and display available reports to the user. Is this possible?
My Code is as follows (still in development):
ServerReport sr = new ServerReport();
sr.ReportPath = reportViewer1.ServerReport.ReportPath;
sr.ReportServerUrl = new Uri(Path);
ReportParameterInfoCollection rpc = sr.GetParameters();
if (rpc.Count > 0)
Console.WriteLine("New");
string outputPath = #"C:\Temp\PdfReport.pdf";
string mimeType;
string encoding;
string extension;
string[] streams;
Warning[] warnings;
byte[] pdfBytes= sr.Render("PDF", string.Empty, out mimeType,
out encoding, out extension, out streams, out warnings);
// save the file
using (FileStream fs = new FileStream(outputPath, FileMode.Create))
{
fs.Write(pdfBytes, 0, pdfBytes.Length);
fs.Close();
}
I use the ReportingService2010 web service to retrieve all deployed items (data sources, shared data sets and reports) and also to deploy directly to Reporting Services.
Here is just one example of the many methods available:
http://msdn.microsoft.com/en-us/library/reportservice2010.reportingservice2010.listchildren.aspx
The ListChildren method will return all items (as a CatalogItem object) under a folder. If you give it the root folder, it will return everything. You should then be able to determine what item each CatalogItem represents.
Hope that helps,
Ash
For anyone else having this problem and would like more information about Ash Shah's answer, see this SO post:
How do I get a list of the reports available on a reporting services instance
Web systems (exact same site) has been migrated to new servers. The mime-type tif file attachments worked on the previous servers in production and no code has been changed, but since the migration we cannot open specifically, .tif file. PDF files spin to a blank page in the browser.
The code calls a webservice(which works fine) to get a Cache Document from a JDE environment
object[] file = docA.CacheDocument("/" + path, filename, doctype, xxx.Global.JDEEnvironment);
fileSize = (int)file[0];
mimeType = (string)file[1];
There is no issue returning the mime-type, which is a "image/tiff". Settings have been set on the server level to accept both .tif and .tiff in MIME-TYPE properties.
HttpContext.Current.Response.ClearHeaders();
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.Buffer = true;
HttpContext.Current.Response.ContentType = mimeType;
string tempPath = "/" + path;
string tempFile = filename;
int i = 0;
while (i < fileSize)
{
int[] byteRangeAry = new int[2];
byteRangeAry[0] = i;
if ((i + _chunkSize) < fileSize)
{
byteRangeAry[1] = i + _chunkSize;
}
else
{
byteRangeAry[1] = fileSize;
}
var docdata = docA.GetByteRange(tempPath, tempFile, byteRangeAry);
HttpContext.Current.Response.BinaryWrite(docdata);
HttpContext.Current.Response.Flush();
//Move the index to the next chunk
i = byteRangeAry[1] + 1;
}
HttpContext.Current.Response.Flush();
this snipit is untouched code that worked in production and now errors out with an object reference error.
var docdata = docA.GetByteRange(tempPath, tempFile, byteRangeAry);
However when I add a .mime extention to the tempFile, it no longer errors out and gets the byteRange.
var docdata = docA.GetByteRange(tempPath, tempFile + ".mime", byteRangeAry);
The dialog box appears - downloads the file - but opens to a blank or an error saying the file appears to be damages, corrupted or is too large. I have tried opening in several other formats to no avail. This happens with the .tif file. The PDF just leaves a blank page in the brower without an option download dialog box.
This is the same code that worked in production and is a .NET V2 app. Any suggestions would be much appreciated.
This was resolved, it was a cacheing issue. We re-wrote the Get CacheDocument method that was corrupting the header. Now its a GetDocument method and we are now able to grab documents, and load them. The problem was the code, it is still strange that it worked in the previous production.
Currently I have SQL Reporting Services 2005 set up, with the report manager at a URL on which users can access reports. The reports are working great there.
My issue is trying to generate these reports in C# .net 4.0 code without any user interaction (such as using the report viewer on screen). I would like to generate and export a report to a PDF file in a C# .net application. The reports have required parameters so I would need to pass the parameters to the report. How can I do this?
I have been searching around online, and either I'm using the wrong keywords or there isn't much information on this. I am quite amazed at how difficult it has been to find information on this, as I would expect it to be a fairly common question. Any and all advice / help is appreciated.
I've not used the 2005 version of the ReportViewer much. But you should be able to do something like this:
ServerReport serverReport = new ServerReport();
serverReport.ReportPath = "path/to/report";
serverReport.ReportServerCredentials = ...;
serverReport.ReportServerUrl = "http://....";
serverReport.SetParameters(...);
string mimeType;
string encoding;
string extension;
string[] streams;
Warning[] warnings;
byte[] asPdf = serverReport.Render("PDF", string.Empty, out mimeType, out encoding, out extension, out streams, out warnings);
The general takeaway being that ServerReport and LocalReport were both designed to be usable outside of a ReportViewer.
string outputPath = "C:\Temp\PdfReport.pdf";
ReportViewer reportViewer = new ReportViewer();
reportViewer.ServerReport serverReport = new ServerReport();
reportViewer.ServerReport.ReportPath = #"path/to/report";
reportViewer.ServerReport.ReportServerUrl = new Uri(#"http://...");
reportViewer.ProcessingMode = ProcessingMode.Local;
reportViewer.ServerReport.ReportServerCredentials.NetworkCredentials = new
System.Net.NetworkCredential(username, password, domain)
List<ReportParameter> parameters = new List<ReportParameter>();
parameters.Add(new ReportParameter("parameterName", "value"));
string mimeType;
string encoding;
string extension;
string[] streams;
Warning[] warnings;
byte[] pdfBytes= serverReport.Render("PDF", string.Empty, out mimeType,
out encoding, out extension, out streams, out warnings);
// save the file
using (FileStream fs = new FileStream(outputPath, FileMode.Create))
{
fs.Write(pdfBytes, 0, pdfBytes.Length);
fs.Close();
}
I had a similar issue where I wanted to open the report as a PDF. If you just need to open a pdf with parameters in a browser window then you can use the report server itself and specify Format=PDF as a querystring option.
Example:
http://myServer/ReportServer/Pages/ReportViewer.aspx?%2fMyApplicationReports%2fAcutalReportFileName&rs:Command=Render&rs:Format=PDF&ParamOneId=31943&ParamTwoDate=17072015
I hope this saves someone else out there some time!