i am developing web application, in my app i have to print rdlc without preview.my code is following
LocalReport report = new LocalReport();
report.ReportEmbeddedResource = "TCESS.ESales.CommonLayer.Reports.HandlingBillReport.rdlc";
report.ReportPath="TCESS.ESales.CommonLayer.Reports.HandlingBillReport.rdlc";
SettlementOfAccountsDTO objSettlementOfAccountsDTO = ESalesUnityContainer.Container.Resolve<ISettlementOfAccountsService>().GetSettlementOfAccountsByAccId(32);
if (objSettlementOfAccountsDTO.Account_Id > 0)
{
SetReportParametersForBill(objSettlementOfAccountsDTO, AccountReportViewer, report);
}
Export(report);
m_currentPageIndex = 0;
Print();
private Stream CreateStream(string name, string fileNameExtension, Encoding encoding,
string mimeType, bool willSeek)
{
Stream stream = new FileStream(name + "." + fileNameExtension, FileMode.Create);
m_streams.Add(stream);
return stream;
}
private void Export(LocalReport report)
{
string deviceInfo =
"<DeviceInfo>" +
" <OutputFormat>EMF</OutputFormat>" +
" <PageWidth>8.5in</PageWidth>" +
" <PageHeight>11in</PageHeight>" +
" <MarginTop>0.25in</MarginTop>" +
" <MarginLeft>0.25in</MarginLeft>" +
" <MarginRight>0.25in</MarginRight>" +
" <MarginBottom>0.25in</MarginBottom>" +
"</DeviceInfo>";
Warning[] warnings;
m_streams = new List<Stream>();
report.Render("Image", deviceInfo, CreateStream, out warnings);
foreach (Stream stream in m_streams)
stream.Position = 0;
}
private void PrintPage(object sender, PrintPageEventArgs ev)
{
Metafile pageImage = new Metafile(m_streams[m_currentPageIndex]);
ev.Graphics.DrawImage(pageImage, 0, 0);
m_currentPageIndex++;
ev.HasMorePages = (m_currentPageIndex < m_streams.Count);
}
private void Print()
{
const string printerName = "\\\\193.168.0.20\\Printer_Q3";
if (m_streams == null || m_streams.Count == 0)
return;
PrintDocument printDoc = new PrintDocument();
printDoc.PrinterSettings.PrinterName = printerName;
if (!printDoc.PrinterSettings.IsValid)
{
string msg = String.Format("Can't find printer \"{0}\".", printerName);
Console.WriteLine(msg);
return;
}
int i=0;
foreach (Stream stream in m_streams)
{
Metafile pageImage = new Metafile(stream);
pageImage.Save(Server.MapPath("~/Images/"+i.ToString()+".jpg"));
i++;
}
//printDoc.PrintPage += new PrintPageEventHandler(PrintPage);
//printDoc.Print();
}
i am getting error "The report definition for report ' ' has not been specified"
on line
report.Render("Image", deviceInfo, CreateStream, out warnings);
I just ran into this problem while instantiating a report to export and had to set this property like this:
wrvReport.LocalReport.ReportEmbeddedResource = "CommonLayer.Reports.SalesByPrice.rdlc";
The difference I see is the .LocalReport is the sub-property to set the embedded resource.
From MSDN:
An embedded report resource is a report definition that has been
stored as a resource in the calling assembly.
If the ReportPath property has been set, the ReportEmbeddedResource
property is ignored.
Therefore, setting the EmbeddedResource property is effectively doing nothing and your ReportPath is also failing because it expects a physical file system path.
I had the same problem. I solved it by setting "Copy to Output Directory = Copy if newer". Cheers.
I also had the same problem, that means that your code is not finding the rdlc file, you need to either use report.ReportEmbeddedResource or report.ReportPath. Looking at your code seems to me that you only need to use report.ReportEmbeddedResource, the other option is for a rdlc that is located in a specific location in your pc or in a network file system
Related
I am using Microsoft.Report.Viewer for generate PDF in my ASP .NET WEB API application. So far when my report get the data directly from database, there is no problem. The problem is, when I try to create a report with subreport within and the subreport data is got from code in a list form, I didn't get the expected result. What I do is create a report with subreport from this tutorial. But when I generate the PDF, what I get is this message .
Here is my code :
My Web API to generate the PDF :
[Route("GeneratePDFForDailyProgram")]
[HttpGet]
[AllowAnonymous]
public async Task<IHttpActionResult> GeneratePDFForDailyProgram(int id) {
string guid = Guid.NewGuid().ToString();
string fileName = string.Concat("Booking_No" + Convert.ToString(id) + "_" + guid.ToUpper() + ".pdf");
string filePath = HttpContext.Current.Server.MapPath("~/Content/Temp/" + fileName);
string name = Request.RequestUri.GetLeftPart(UriPartial.Authority) + System.Configuration.ConfigurationManager.ConnectionStrings[System.Configuration.ConfigurationManager.AppSettings["CUSTOMPORT"]];
string name2 = Request.GetRequestContext().VirtualPathRoot;
List<TourDestination> destination = new List<TourDestination>();
TourTransactionSummaryViewModel summaryViewModel = new TourTransactionSummaryViewModel();
try {
//summaryViewModel = await CalcSummaryViewModel(transaction, summaryViewModel, db);
summaryViewModel.DailyPrograms = DailyProgram(id);
destination = TourDestination(summaryViewModel.DailyPrograms);
List < Movement > movementList = summaryViewModel.DailyPrograms.FirstOrDefault().Movements.ToList();
Reports.ReportGenerator.GeneratePDFForDailyProgram(summaryViewModel.DailyPrograms, destination, filePath);
//await Reports.ReportGenerator.GeneratePDFForMovement(movementList, filePath);
HttpResponseMessage result = null;
result = Request.CreateResponse(HttpStatusCode.OK);
result.Content = new StreamContent(new FileStream(filePath, FileMode.Open));
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = fileName;
result.Dispose();
string convertedFilePath = filePath.Replace(#"\\", #"\");
} catch (Exception ex) {
return BadRequest(ex.Message);
}
return Ok(name + name2 + "/Content/Temp/" + fileName);
}
As you can see from the code above, I use GeneratePDFForDailyProgram method to generate the PDF.
Here my GeneratePDFForDailyProgram method :
public static bool GeneratePDFForDailyProgram(TourTransactionSummaryViewModel.DailyProgram[] dailyPrograms, List<TourDestination> destination , string filePath) {
try {
string binPath = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "bin");
var assembly = Assembly.Load(System.IO.File.ReadAllBytes(binPath + "\\TripPlannerAPI.dll"));
using (Stream stream = assembly.GetManifestResourceStream(DailyProgramReport)) {
var viewer = new ReportViewer();
viewer.LocalReport.EnableExternalImages = true;
viewer.LocalReport.LoadReportDefinition(stream);
Warning[] warnings;
string[] streamids;
string mimeType;
string encoding;
string filenameExtension;
viewer.LocalReport.SubreportProcessing += new Microsoft.Reporting.WebForms.SubreportProcessingEventHandler(LocalReport_SubreportProcessing);
viewer.LocalReport.DataSources.Add(new ReportDataSource("DailyProgram", dailyPrograms));
byte[] bytes = viewer.LocalReport.Render(
"PDF", null, out mimeType, out encoding, out filenameExtension,
out streamids, out warnings);
using (FileStream fs = new FileStream(filePath, FileMode.Create)) {
fs.Write(bytes, 0, bytes.Length);
fs.Flush();
}
stream.Flush();
}
} catch (Exception ex) {
return false;
}
return true;
}
To run the SubReport, I use the eventhandler code :
private static void LocalReport_SubreportProcessing(object sender, SubreportProcessingEventArgs e) {
DateTime movementDate = Convert.ToDateTime(e.Parameters[0].Values[0]);
TourTransactionsController controller = new TourTransactionsController();
var movement = controller.Movements();
List<Movement> movementList = new List<Movement>();
movementList.Add(new Movement {
Destination = "TEST",
MovementDescription = "TEST",
DateTime = Convert.ToDateTime("2017-09-25") //HARDCODE FOR TEST
});
e.DataSources.Clear();
e.DataSources.Add(new Microsoft.Reporting.WebForms.ReportDataSource() {
Name = "DSMovements",
Value = movementList
});
//throw new NotImplementedException();
}
What I did try :
Check the sub report name, and change it from report name to report file url. Still get the same message.
Generate the Sub Report directly, not from the main report. The subreport is successfully generated.
PS : When I debug my code, and put a breakpoint in my event handler LocalReport_SubreportProcessing the breakpoint is not hitting while debugging
My Questions are :
Why my breakpoint on the eventhandler is not hitting while debugging ?
Is it possible that eventhandler which is not hitting while debugging, could be the reason I got the message The subreport 'MovementReport' could not be
found at the specified location MovementReport.
Please verify that the subreport has been
published and that the name is correct. ?
Is there any other way for me to create a main report with data from db, and the subreport with data from code in list form ?
Any help is appreciated.
We have implemented a process using C# and reportviewer to create PDFs by the localreport.render method.
When we have to process a big file, say more than 20000 records, the process fails with outofmemory exception error. I know there may be lot of causes for this error but what I want to know is, if the below code is okay or if you expert can give me a better solution.
I have about 40 case statements each calling different .rdlc files and it is based on the type (I did not include all the case statements due to lack of space).
USP_Select_Batch_Address_To_Sort is a dataset defined in the solution executing a stored procedure accepting three parameters (in this case batch, run and sequence#).
So is this approach feasible? What other solution can you provide?
public static void GenerateIndividualPDFs(string batch, string run, MainDataSet1 DS, MainDataSet1TableAdapters.USP_Select_Batch_Address_To_SortTableAdapter Ta, BindingSource bs, int intStart = 0, int intEnd = 0, string strLetterType = "")
{
reportDataSource.Name = "DataSet1";
reportDataSource.Value = bs;
int count;
SqlDataAdapter adapter;
var batchinfo = new clsBatchInfo();
ReportViewer report = new ReportViewer();
report.LocalReport.DataSources.Add(reportDataSource);
if (!Directory.Exists(mstrFilePath + "\\" + batch + run))
{
DirectoryInfo di = Directory.CreateDirectory(mstrFilePath + "\\" + batch + run);
}
var DA = new clsGetBatchSort();
//this dataAdapter will print the full set
adapter = new SqlDataAdapter(DA.dsBatch_Sort(batch, run));
DataSet ds = new DataSet();
adapter.Fill(ds);
count = ds.Tables[0].Rows.Count;
int i = 0;
int LetterTypeID = 0;
report.ProcessingMode = ProcessingMode.Local;
foreach (DataRow dr in ds.Tables[0].Rows)
{
i++;
report.Clear();
Ta.ClearBeforeFill = true;
try
{
LetterTypeID = Convert.ToInt32(dr[2]);
switch (LetterTypeID)
{
case 1:
{
Ta.Fill(DS.USP_Select_Batch_Address_To_Sort, Convert.ToDecimal(batch), run, Convert.ToInt32(dr["MPresortID"]));
report.LocalReport.ReportEmbeddedResource = "ReportsApplication1.ABC.MAENG.rdlc";
ExportReport(Convert.ToInt32(dr["MPresortID"]), batch, run, report);
continue;
}
case 2:
{
Ta.Fill(DS.USP_Select_Batch_Address_To_Sort, Convert.ToDecimal(batch), run, Convert.ToInt32(dr["MPresortID"]));
report.LocalReport.ReportEmbeddedResource = "ReportsApplication1.ABC.MASPA.rdlc";
ExportReport(Convert.ToInt32(dr["MPresortID"]), batch, run, report);
continue;
}
catch (Exception ex)
{
clsEmail.EmailMessage("Error Batch " + batch + run, "clsGenerateLetters " + ex.Message);
continue;
//MessageBox.Show(ex.Message);
//return "";
}
}
}
private static void ExportReport(int PreSortID, string batch, string run, ReportViewer Report)
{
Report.RefreshReport();
Warning[] warnings;
string[] streamids;
string mimeType;
string encoding;
string filenameExtension;
string fmt = "00000000";
byte[] bytes = Report.LocalReport.Render(
"PDF", null, out mimeType, out encoding, out filenameExtension,
out streamids, out warnings);
string filename = mstrFilePath + "\\" + batch + run + "\\" + PreSortID.ToString(fmt) + ".PDF";
using (FileStream fs = new FileStream(filename, FileMode.Create))
{
fs.Write(bytes, 0, bytes.Length);
fs.Close();
}
Report.LocalReport.ReleaseSandboxAppDomain();
}
I have a master report file and a sub report file.
Master report file calls sub report file.
Let's have a look at the code first.
private void CreatePDF(string fileName)
{
try
{
// Variables
Warning[] warnings;
string[] streamIds;
string mimeType = string.Empty;
string encoding = string.Empty;
string extension = string.Empty;
string _strGijunMonth = DateTime.Parse(GijunMonth).ToString("yyyyMM");
byte[] bytes = null;
// Setup the report viewer object and get the array of bytes
ReportViewer viewer = new ReportViewer();
viewer.LocalReport.DataSources.Clear();
viewer.ProcessingMode = ProcessingMode.Local;
viewer.LocalReport.ReportEmbeddedResource = "MasterReport.rdlc";
viewer.LocalReport.EnableExternalImages = true;
DataTable _dt = base.GetDataTable(
"my_procedure"
, _strMainNo
);
_intTotalPage = _dt.Rows.Count * 2;
ReportDataSource _ds = new ReportDataSource();
_ds.Value = _dt;
_ds.Name = "SetData";
viewer.LocalReport.DataSources.Add(_ds);
// sub report event
viewer.LocalReport.SubreportProcessing += new SubreportProcessingEventHandler(LocalReport_SubreportProcessing);
// print
viewer.RefreshReport();
bytes = viewer.LocalReport.Render("PDF", null, out mimeType, out encoding, out extension, out streamIds, out warnings);
System.IO.FileStream newFile1 = new System.IO.FileStream(fileName, System.IO.FileMode.Create);
newFile1.Write(bytes, 0, bytes.Length);
newFile1.Close();
}
catch
{
throw;
}
}
void LocalReport_SubreportProcessing(object sender, SubreportProcessingEventArgs e)
{
try
{
string MAINT_NO = e.Parameters["MAINT_NO"].Values[0];
string _strGijunMonth = DateTime.Parse(GijunMonth).ToString("yyyyMM");
// get sub report procedure
DataSet _dsCust_Info = base.GetDataSet(
"my_sub_procedure"
, MAINT_NO
, _strGijunMonth
);
----> by somehow, it should throw error. If so, I should not print error page to pdf.
}
catch (Exception err)
{
}
}
My application calls "CreatePDF" method with file name argument.
Let's say that I have to print to PDF 5 pages.
While calling LocalReport_SubreportProcessing event, some of sub reports have error value in data. So, I throw an error in LocalReport_SubreportProcessing event.
For example, when I say that there are 5 pages and only 1, 2, 3 and 5 pages are okay and the number 4 page should not be printed as PDF.
I wonder how I can delete PDF page which is already created by ReportViewer.
As you can see, LocalReport_SubreportProcessing event comes after creating PDF file.
Anyone has any idea to fix this problem?
Maybe reportViewer.CancelRendering(0);
when you detect an error?
I am trying to upload JPG file to a folder I have created in my project.
The image does not get saved in the images folder. It displays my image when I upload but the image itself is not present in images folder.
Here is the code i am using:
private void btnUpload_Click(object sender, System.EventArgs e)
{
// Initialize variables
string sSavePath;
string sThumbExtension;
int intThumbWidth;
int intThumbHeight;
// Set constant values
sSavePath = "images/";
sThumbExtension = "_thumb";
intThumbWidth = 160;
intThumbHeight = 120;
// If file field isn’t empty
if (filUpload.PostedFile != null)
{
// Check file size (mustn’t be 0)
HttpPostedFile myFile = filUpload.PostedFile;
int nFileLen = myFile.ContentLength;
if (nFileLen == 0)
{
lblOutput.Text = "No file was uploaded.";
return;
}
// Check file extension (must be JPG)
if (System.IO.Path.GetExtension(myFile.FileName).ToLower() != ".jpg")
{
lblOutput.Text = "The file must have an extension of JPG";
return;
}
// Read file into a data stream
byte[] myData = new Byte[nFileLen];
myFile.InputStream.Read(myData,0,nFileLen);
// Make sure a duplicate file doesn’t exist. If it does, keep on appending an
// incremental numeric until it is unique
string sFilename = System.IO.Path.GetFileName(myFile.FileName);
int file_append = 0;
while (System.IO.File.Exists(Server.MapPath(sSavePath + sFilename)))
{
file_append++;
sFilename = System.IO.Path.GetFileNameWithoutExtension(myFile.FileName)
+ file_append.ToString() + ".jpg";
}
// Save the stream to disk
System.IO.FileStream newFile
= new System.IO.FileStream(Server.MapPath(sSavePath + sFilename),
System.IO.FileMode.Create);
newFile.Write(myData,0, myData.Length);
newFile.Close();
// Check whether the file is really a JPEG by opening it
System.Drawing.Image.GetThumbnailImageAbort myCallBack =
new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);
Bitmap myBitmap;
try
{
myBitmap = new Bitmap(Server.MapPath(sSavePath + sFilename));
// If jpg file is a jpeg, create a thumbnail filename that is unique.
file_append = 0;
string sThumbFile = System.IO.Path.GetFileNameWithoutExtension(myFile.FileName)
+ sThumbExtension + ".jpg";
while (System.IO.File.Exists(Server.MapPath(sSavePath + sThumbFile)))
{
file_append++;
sThumbFile = System.IO.Path.GetFileNameWithoutExtension(myFile.FileName) +
file_append.ToString() + sThumbExtension + ".jpg";
}
// Save thumbnail and output it onto the webpage
System.Drawing.Image myThumbnail
= myBitmap.GetThumbnailImage(intThumbWidth,
intThumbHeight, myCallBack, IntPtr.Zero);
myThumbnail.Save (Server.MapPath(sSavePath + sThumbFile));
imgPicture.ImageUrl = sSavePath + sThumbFile;
// Displaying success information
lblOutput.Text = "File uploaded successfully!";
// Destroy objects
myThumbnail.Dispose();
myBitmap.Dispose();
}
catch (ArgumentException errArgument)
{
// The file wasn't a valid jpg file
lblOutput.Text = "The file wasn't a valid jpg file.";
System.IO.File.Delete(Server.MapPath(sSavePath + sFilename));
}
}
}
public bool ThumbnailCallback()
{
return false;
}
I'd be surprised if the line myThumbnail.Save (Server.MapPath(sSavePath + sThumbFile)); works...
You are trying to map a file which doesn't exist yet!
Try
myThumbnail.Save(Server.MapPath(sSavePath) + sThumbFile));
Gurus
We are developing a win forms application in .NET 4.0, that generate PDF reports using RDLC control. As the report generation takes lot of time, we decided to implement Parallel for each.. With the following code , it generates the PDF for first record after that, system just hangs.. Do help us...
public void generatereport()
{
button1.Enabled = false;
button4.Enabled = false;
DataTable dtBranch = new DataTable();
dtBranch = getBranchNo(); -- we might get around 300 rows here
try
{
Parallel.ForEach(dtBranch.AsEnumerable(), drow =>
{
// Shows the ReportData along with the branch code
reportdate = drow["reportdate"].ToString();
string branchName = drow["BranchNo"].ToString();
ProcessReport(branchName);
});
reportViewer2.Visible = false;
button1.Enabled = true;
button4.Enabled = true;
lblMsg.Text = "Branch Summary Generated at '" + #fullpath + "'";
}
catch (AggregateException e)
{
//Console.Write(e.Data + e.Message);
//Console.ReadLine();
}
}
private void ProcessReport(string branName)
{
if (reportViewer2.InvokeRequired)
{
ProcessReportCallBack d = new ProcessReportCallBack(ProcessReport);
Invoke(d, new object[] { branName });
}
else
{
log.Debug("branch" + DateTime.Now.ToString());
DataTable dt = new DataTable();
dt = getReportOrderNoBasedonBranchID(branName);//Get all the report order no as per the branch id
this.sp_getReportOrderNoTableAdapter.Fill(this.getRptNo.sp_getReportOrderNo, branName);
this.reportViewer2.LocalReport.SubreportProcessing += new Microsoft.Reporting.WinForms.SubreportProcessingEventHandler(this.reportViewer2_Subreport1);
this.reportViewer2.Clear();
this.reportViewer2.ProcessingMode = ProcessingMode.Local;
this.reportViewer2.LocalReport.ReportPath = #"Master.rdlc";
this.reportViewer2.Refresh();
Savepdf("reportViewer2", branName + "_" + reportdate);
}
}
In save PDF we are generating the PDF report..
byte[] bytes = null;
bytes = reportViewer2.LocalReport.Render(
"PDF", null, out mimeType, out encoding,
out extension,
out streamids, out warnings);
filename = BranchName + '_' + "Summary" + ".pdf";
using (FileStream fs = new FileStream(#fullpath + '\\' + filename, FileMode.Create))
{
fs.Write(bytes, 0, bytes.Length);
fs.Close();
}
bytes = null;
Kindly provide your feedback
you don't need a sample codes to Export to PDF, when the RDLC is already rendered to the ReportViewer try to find this icon from the ToolBars of ReportViewer Control:
EDIT:
Save RDLC reports as PDF programaticaly
public void Save(ReportViewer viewer, string savePath)
{
byte[] Bytes = viewer.LocalReport.Render("PDF", "", null, null, null, null, null);
using (FileStream Stream = new FileStream(savePath, FileMode.Create)) {
Stream.Write(Bytes, 0, Bytes.Length);
}
}