Merge rdlc's rendered as pdf in ActionResult-VBForums
Results 1 to 3 of 3

Thread: Merge rdlc's rendered as pdf in ActionResult

  1. #1

    Thread Starter
    Frenzied Member MattP's Avatar
    Join Date
    Dec 2008
    Location
    WY
    Posts
    1,227

    Merge rdlc's rendered as pdf in ActionResult

    I have an ActionResult that returns a FileContentResult that is working fine.

    c# Code:
    1. [AllowAgencyUser]
    2.         public ActionResult TrainingHours(int id)
    3.         {
    4.             EmployeeModel model = new EmployeeModel(id);
    5.             if (!model.CheckEmployeeAccess())
    6.                 throw new HttpException(403, "Access Denied");
    7.  
    8.             byte[] report = model.GetTrainingHoursReport(id);
    9.             return File(report, Constants.PdfMimeType, model.EmployeeHoursReportFileName);
    10.         }

    byte[] report is returning LocalReport.Render("PDF", deviceInfo) of an rdlc.

    The customer has requested a button on the page where they can get a whole bunch of these reports merged into 1 file.

    c# Code:
    1. [AllowAgencyUser]
    2.         public ActionResult MassTrainingHours(int[] employeeIds)
    3.         {
    4.             if (employeeIds == null)
    5.                 return new EmptyResult();
    6.  
    7.             List<byte[]> reportsList = new List<byte[]>();
    8.             foreach (int employeeId in employeeIds)
    9.             {
    10.                 EmployeeModel model = new EmployeeModel(employeeId);
    11.                 byte[] fileBytes = model.GetTrainingHoursReport(employeeId);
    12.                 reportsList.Add(model.GetTrainingHoursReport(employeeId));
    13.             }
    14.             PdfMerger merger = new PdfMerger();
    15.             byte[] report = merger.MergeFiles(reportsList);
    16.             return File(report, Constants.PdfMimeType, "training_hours.pdf");
    17.         }

    The merge files method:

    c# Code:
    1. public byte[] MergeFiles(List<byte[]> inputFiles)
    2.         {
    3.             MemoryStream outputMS = new MemoryStream();
    4.             Document document = new Document();
    5.             PdfCopy writer = new PdfCopy(document, outputMS);
    6.             PdfImportedPage page = null;
    7.  
    8.             document.Open();
    9.  
    10.             foreach (byte[] fileData in inputFiles)
    11.             {
    12.                 PdfReader reader = new PdfReader(fileData);
    13.                 int n = reader.NumberOfPages;
    14.  
    15.                 for (int i = 1; i <= n; i++)
    16.                 {
    17.                     page = writer.GetImportedPage(reader, i);
    18.                     writer.AddPage(page);
    19.                 }
    20.  
    21.                 PRAcroForm form = reader.AcroForm;
    22.                 if (form != null)
    23.                     writer.CopyAcroForm(reader);
    24.             }
    25.  
    26.             document.Close();
    27.  
    28.             return outputMS.ToArray();
    29.         }

    The problem is that no file is downloaded at all.

    Everything seems to be working properly, I can step through the code all the way through returning the FileContentResult with no problems.

    Anyone have any ideas as to what's wrong with the way I'm trying to do this or have a different approach to merging the files?
    This pattern in common to all great programmers I know: they're not experts in something as much as experts in becoming experts in something.

    The best programming advice I ever got was to spend my entire career becoming educable. And I suggest you do the same.

  2. #2

    Thread Starter
    Frenzied Member MattP's Avatar
    Join Date
    Dec 2008
    Location
    WY
    Posts
    1,227

    Re: Merge rdlc's rendered as pdf in ActionResult

    Thought it might be an issue with the output coming out of iTextSharp so I made a method using PdfSharp.

    c# Code:
    1. public byte[] MergeFiles(List<byte[]> inputFiles)
    2.         {
    3.             PdfDocument outputDocument = new PdfDocument();
    4.  
    5.             foreach (byte[] fileData in inputFiles)
    6.             {
    7.                 MemoryStream reportStream = new MemoryStream(fileData);
    8.                 PdfDocument report = PdfReader.Open(reportStream, PdfDocumentOpenMode.Import);
    9.                 for (int idx = 0; idx < report.PageCount; idx++)
    10.                 {
    11.                     PdfPage page = report.Pages[idx];
    12.                     page = outputDocument.AddPage(page);
    13.                 }
    14.             }
    15.  
    16.             byte[] contents = null;
    17.             using (MemoryStream stream = new MemoryStream())
    18.             {
    19.                 outputDocument.Save(stream, true);
    20.                 contents = stream.ToArray();
    21.             }
    22.  
    23.             return contents;
    24.         }

    The same thing is happening here as well.

    Any ideas?
    This pattern in common to all great programmers I know: they're not experts in something as much as experts in becoming experts in something.

    The best programming advice I ever got was to spend my entire career becoming educable. And I suggest you do the same.

  3. #3

    Thread Starter
    Frenzied Member MattP's Avatar
    Join Date
    Dec 2008
    Location
    WY
    Posts
    1,227

    Re: Merge rdlc's rendered as pdf in ActionResult

    Thought it might be an issue with the files that are being generated by the system so I tried it from a winforms app and used the files that the MVC app created.

    c# Code:
    1. private void Form1_Load(object sender, EventArgs e)
    2.         {
    3.             List<byte[]> reportsList = new List<byte[]>();
    4.             reportsList.Add(GetFileBytes(@"C:\Temp\needs_hours.pdf"));
    5.             reportsList.Add(GetFileBytes(@"C:\Temp\training_hours.pdf"));
    6.             PdfMerger merger = new PdfMerger();
    7.             merger.MergeFiles(reportsList, @"C:\Temp\merged_reports.pdf");
    8.         }
    9.  
    10.         private byte[] GetFileBytes(string fileFullPath)
    11.         {
    12.             return File.ReadAllBytes(fileFullPath);
    13.         }

    Slightly modified MergeFiles method to go to a FileStream rather than return a MemoryStream

    c# Code:
    1. public void MergeFiles(List<byte[]> inputFiles, string outputFile)
    2.         {
    3.             FileStream fs = new FileStream(outputFile, FileMode.Create);
    4.             Document document = new Document();
    5.             PdfCopy writer = new PdfCopy(document, fs);
    6.  
    7.             PdfImportedPage page = null;
    8.  
    9.             document.Open();
    10.  
    11.             foreach (byte[] fileData in inputFiles)
    12.             {
    13.                 PdfReader reader = new PdfReader(fileData);
    14.                 int n = reader.NumberOfPages;
    15.  
    16.                 for (int i = 1; i <= n; i++)
    17.                 {
    18.                     page = writer.GetImportedPage(reader, i);
    19.                     writer.AddPage(page);
    20.                 }
    21.  
    22.                 PRAcroForm form = reader.AcroForm;
    23.                 if (form != null)
    24.                     writer.CopyAcroForm(reader);
    25.             }
    26.  
    27.             document.Close();
    28.             fs.Close();
    29.         }

    This works exactly like I expect it to.
    This pattern in common to all great programmers I know: they're not experts in something as much as experts in becoming experts in something.

    The best programming advice I ever got was to spend my entire career becoming educable. And I suggest you do the same.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width

Survey posted by VBForums.