I'm using RDLC file to render a report (without SQL Server Reporting Services) and return it from my controller as a file. This is part of my MVC web application.
public ActionResult Index()
{
var report = new LocalReport();
report.ReportPath = Path.Combine(Server.MapPath("~/Reports"), "Report1.rdlc");
var reportData = new List<MonthlyData> {
new MonthlyData {RecordNo=1, Tid="123456", Active=10, Inactive=1}
};
ReportDataSource rd = new ReportDataSource("DataSet1", reportData);
report.DataSources.Add(rd);
string reportType = "PDF";
string mimeType;
string encoding;
string fileNameExtension;
string deviceInfo =
"<DeviceInfo>" +
" <OutputFormat>" + "PDF" + "</OutputFormat>" +
//" <PageWidth>8.5in</PageWidth>" +
//" <PageHeight>11in</PageHeight>" +
//" <MagroupinTop>0.5in</MagroupinTop>" +
//" <MagroupinLeft>1in</MagroupinLeft>" +
//" <MagroupinRight>1in</MagroupinRight>" +
//" <MagroupinBottom>0.5in</MagroupinBottom>" +
"</DeviceInfo>";
Warning[] warnings;
string[] streams;
byte[] renderedBytes;
renderedBytes = report.Render(
reportType,
deviceInfo,
out mimeType,
out encoding,
out fileNameExtension,
out streams,
out warnings);
return File(renderedBytes, mimeType);
}
This is the result:
table example in rdlc file
Everything works like a charm until I decide to add a chart.
rdlc file with chart
Now when I render it I get two exceptions:
Microsoft.Reporting.WebForms.LocalProcessingException: „An error occurred during local report processing.”
DefinitionInvalidException: The definition of the report 'C:\Users\agutowski\Documents\Visual Studio 2017\Projects\rdlcMvc\rdlcMvc\Reports\Report1.rdlc' is invalid.
and
Microsoft.Reporting.WebForms.LocalProcessingException: „An error occurred during local report processing.”
ReportProcessingException: The definition of this report is not valid or supported by this version of Reporting Services. The report definition may have been created with a later version of Reporting Services, or contain content that is not well-formed or not valid based on Reporting Services schemas. Details: The report definition has an invalid target namespace 'http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition' which cannot be upgraded.
I already tried different versions of Microsoft.ReportViewer.Common and Microsoft.ReportViewer.WebForms.
I solved it by using Microsoft.ReportingServices.ReportViewerControl.WebForms and Microsoft.SqlServer.Types NuGet packages instead of Microsoft.ReportViewer.Common and Microsoft.ReportViewer.WebForms.
Related
I am attempting to produce a c# program to run an SSRS report on any one of a number of identical databases, the target database to be specified at run-time. To this end, I create a solution and project, and in this project include an SSRS report. This report has a dataset LegislationData which invokes a stored procedure in a specimen database.
I am now trying to get this to run in the C# project. I create a form with a report viewer and a go button and attempt to set up the report. I envisaged some code along the following lines:-
MyReport my_report = new MyReport();
my_report.ConnectionString = "blah blah"; // or
my_report.DataSet.ConnectionString = "blah blah"; // or
my_report.LegislationData.ConnectionString = "blah blah"
and then
report_viewer.Report = my_report; // or
report_viewer.LocalReport = my_report; // or
report_viewer.SetReport(my_report);
but none of these things actually exist.
Can someone explain to me very slowly and in words of one syllable what I need to do here? I have looked at the answers to similar questions here and here but to be frank the answers make no sense.
The first thing you need to realise is that SSRS has to be added into your C# application as a web reference. There's a guide on how to do this here: https://msdn.microsoft.com/en-gb/library/ms169926.aspx. Basically it sounds worse than it is, and it should only take a few minutes to configure all this. I found that MSDN link was corrupted for me, so here's another place that discusses how to do this: https://sqluninterrupted.com/2012/03/04/adding-a-reporting-services-web-reference-to-net-application/.
Once you have your report running from a C# application you will need to decide what you want to do with the output, convert it to PDF, stream it to the screen, save it as Excel, etc.
I haven't done this before, but it looks as though you can embed a data source into your report that uses an expression based on a parameter. So you would pass in a parameter to run the report that would be a connection string. You would also need to pass in any other parameters you might have in your report.
So step 1 add the web reference for SSRS.
Step 2 add some code to run your report, e.g. here's an example that returns the report as a byte array in PDF format:
public byte[] RenderReport(ReportExecutionService rs, string reportName, int variant)
{
Console.WriteLine("Rendering " + reportName + "_" + variant.ToString("00"));
byte[] result = null;
string reportPath = "/Prototypes/Inheritance Letters/" + reportName;
const string format = "PDF";
const string devInfo = #"<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>";
//Prepare report parameters
var parameters = new ParameterValue[2];
parameters[0] = new ParameterValue { Name = "row_id", Value = variant.ToString() };
parameters[1] = new ParameterValue { Name = "bulk_run", Value = "1" };
rs.ExecutionHeaderValue = new ExecutionHeader();
rs.LoadReport(reportPath, null);
rs.SetExecutionParameters(parameters, "en-gb");
try
{
string encoding;
string mimeType;
string extension;
Warning[] warnings;
string[] streamIDs;
result = rs.Render(format, devInfo, out extension, out encoding, out mimeType, out warnings, out streamIDs);
rs.GetExecutionInfo();
return result;
}
catch (SoapException e)
{
Console.WriteLine(e.Detail.OuterXml);
return null;
}
}
Step 3 pass the connection string as one of the parameters, and use an expression in an embedded data source in your report to pick this up and use it.
Step 4 decide what to do with the rendered output. For example, here I render a report then save the output to a PDF:
byte[] result = new Render().RenderReport(rs, "ACQ_Welcome_Letter", i);
new Render().CreatePDF(i, "Welcome Letter", "ACQ_Welcome_Letter" + "_" + fuelType, result);
Here's the CreatePDF method, it has a lot of other garbage in for my particular solution, but it gives you a taste of how to do this:
public string CreatePDF(int variant, string subFolder, string reportName, byte[] result)
{
//We want 16 variants, but we pass in a number from 1 to 48, so use modulo division to convert this back to a 1 to 16 range
variant = (variant - 1) % 16 + 1;
Console.WriteLine("Saving " + reportName + "_Variant_" + variant.ToString("00") + ".pdf");
try
{
//Determine the target folder/ filename for the PDF
//Snail Mail has its own folder, all PDFs go into that folder and then are manually processed
string folder = #"S:\Change Management Documents\SMETS1\Inheritance Comms\" + subFolder + #"\";
string filename = reportName + "_Variant_" + variant.ToString("00") + ".pdf";
//Remove any existing content
string[] filePaths = Directory.GetFiles(folder, filename);
foreach (string filePath in filePaths)
File.Delete(filePath);
//Now save the PDF
string path = folder + #"\" + filename;
FileStream stream = File.Create(path, result.Length);
stream.Write(result, 0, result.Length);
stream.Close();
return filename;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return "";
}
}
I'm facing one of the most strangest technical problem in .NET. I've written following logic to export report to PDF which is working in all the systems except Windows Server 2012. What could be the problem? I tried using the latest Microsoft.ReportViewer.Winforms.dll, but that too didn't help. Please help me if someone has any idea to deal with this.
reportViewer = new ReportViewer();
Warning[] warnings;
string[] streamids;
string mimeType, encoding, filenameExtension;
Assembly assembly = Assembly.LoadFrom(report.AssemblyName);
Stream stream = assembly.GetManifestResourceStream(report.ReportName);
reportViewer.LocalReport.LoadReportDefinition(stream);
//reportViewer.LocalReport.DataSources.Clear();
//reportViewer.ProcessingMode = ProcessingMode.Local;
//lr = reportViewer.LocalReport;
//lr.ReportPath = "Reports\\CommentReport.rdlc";
reportViewer.LocalReport.DataSources.Clear();
foreach (var dataSource in report.DataSources)
{
reportViewer.LocalReport.DataSources.Add(new ReportDataSource(dataSource.Key, dataSource.Value));
}
pdfByteArray = reportViewer.LocalReport.Render("PDF", null, out mimeType, out encoding, out filenameExtension, out streamids, out warnings);
I have my reports in a Reporting Services server, inside my .rdl there is a query that accepts parameters. I pass those parameters with an instance of ReportViewer. I have a method that downloads the result of the report in Excel format without using the ReportViewer directly. The method is the following:
private void CreateEXCEL(Dictionary<string, string> parametros, string nombreReporte)
{
// Variables
Warning[] warnings;
string[] streamIds;
string mimeType = string.Empty;
string encoding = string.Empty;
string extension = string.Empty;
// Setup the report viewer object and get the array of bytes
string ReportServerURL = ConfigurationManager.AppSettings["ReportServerCompletitudURL"];
string ReportName = ConfigurationManager.AppSettings["ReportNameRankingVentaPDV"] + "/" + nombreReporte;
MyReportViewer.Reset();
MyReportViewer.ProcessingMode = ProcessingMode.Remote;
MyReportViewer.ServerReport.ReportPath = ReportName;
MyReportViewer.ServerReport.ReportServerUrl = new Uri(ReportServerURL);
List<ReportParameter> parameters = new List<ReportParameter>();
foreach (var d in parametros)
{
parameters.Add(new ReportParameter(d.Key, d.Value));
}
MyReportViewer.ServerReport.SetParameters(parameters);
byte[] bytes = MyReportViewer.ServerReport.Render("EXCEL", null, out mimeType, out encoding, out extension, out streamIds, out warnings);
// Now that you have all the bytes representing the PDF report, buffer it and send it to the client.
Response.Buffer = true;
Response.Clear();
Response.ContentType = mimeType;
Response.AddHeader("content-disposition", "attachment; filename=" + nombreReporte + "." + extension);
Response.BinaryWrite(bytes); // create the file
Response.Flush(); // send it to the client to download
}
Now the idea is that I can't create a file with more that 65536 rows as an Excel file, the idea is to "Ask" if the result of the query inside the Report will yield more than 65k rows, then use csv format.
I dont see that reportviewer server control have a method that checks the result of the query.
I don't want to use pagebreaks inside the SSRS reports. Is there any way to ask in my code behind?
Not sure if this helps but this is a work around for exporting to excel.
Create a parent group on the tablix (or table, or list) and in the Group on: field enter the expression below.
Add Page break between each instance of a group
=CInt(Ceiling(RowNumber(nothing)/65000))
See Question on Here.
I found the solution to this particular problem like this:
Put this expression in my "Details" Group. In Disabled property: =IIF(rownumber(nothing) mod 10000=0,false,true) BreakLocation: End.
After this change, I can save this excel divided in different worksheets in the same excel sheet for every 10k rows. I tried doing the ceiling but if you have a rownumber expression inside that group it wont work.
I am using ASP.NET MVC and i want to render an rdlc in a view.
Here is my code to render the rdlc file.
[HttpPost]
public ActionResult DepartmentwiseInwardOutwardReport(int? fd, int? td, string fdt, string tdt)
{
TrackBL trackBL = new TrackBL();
IEnumerable<TrackModel> trackList = trackBL.GetDeptInwardOutwardReport(fd, td, fdt, tdt);
//return PartialView("_TrackingSearchReport", trackList);
LocalReport localReport = new LocalReport();
localReport.ReportPath = Server.MapPath("~/Content/Reports/FileMovement.rdlc");
ReportDataSource reportDataSource = new ReportDataSource("Customers", trackList);
reportDataSource.Name = "FTSDataSet_proc_File_InwardOutWardReport";
localReport.DataSources.Add(reportDataSource);
string reportType = "PDF";
string mimeType;
string encoding;
string fileNameExtension;
//The DeviceInfo settings should be changed based on the reportType
//http://msdn2.microsoft.com/en-us/library/ms155397.aspx
string deviceInfo =
"<DeviceInfo>" +
" <OutputFormat>PDF</OutputFormat>" +
" <PageWidth>8.5in</PageWidth>" +
" <PageHeight>11in</PageHeight>" +
" <MarginTop>0.5in</MarginTop>" +
" <MarginLeft>1in</MarginLeft>" +
" <MarginRight>1in</MarginRight>" +
" <MarginBottom>0.5in</MarginBottom>" +
"</DeviceInfo>";
Warning[] warnings;
string[] streams;
byte[] renderedBytes;
//Render the report
renderedBytes = localReport.Render(
reportType,
deviceInfo,
out mimeType,
out encoding,
out fileNameExtension,
out streams,
out warnings);
//Response.AddHeader("content-disposition", "attachment; filename=NorthWindCustomers." + fileNameExtension);
return File(renderedBytes, mimeType);
When i render this in the view, i am able to see 14 pages, i do have only 1 row to display as of now. two columns each are getting displayed in the page. I wanna display it like a report where all the columns are displayed next to other.
Am i missing some settings? ANy suggestions?
Im using RDLC in MVC3 and even MVC4, I dont have that problem that you are facing, even though I think its related to the RDLC report itself, maybe you have the width of the page very high so its warping it to 14 pages (sometimes with me it warps to 3 pages if I forget to set the orientation and I have a large number of columns.
If you set width of your report to be larger than the page you try to print on, the report will be automatically split to fit pages.
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!