Get PDF file from Report using Code

Hi Everyone,

In this article I want to show you the way how you can dynamically generate PDF file from any report of Acumatica and attach if to an entity.

generate PDF file acumatica

I will do that on example of printing AR Invoice Form out of AR Invoice with custom button

In general that task can be split in 4 steps:

  • Defining reports parameters
  • Creation and processing report
  • Get report as PDF file
  • Attach report to entity
Parameters

All reports have different parameter so before writing a code, check what parameters are required in that report. All parameter should be provided as dictionary – name/value.

Report
To work with reports you need a reference to PX.Reports.dll, so make sure you have added it before compiling code below. To work with reports you can use PX.Reports.Controls.Report class there.

PDF
Acumatica generated PDF in unattended mode mostly for sending reports by email, so here we are going to reuse some of the mailing features:
PX.Reports.Mail.Message.GenerateReport(reportNode, ReportProcessor.FilterPdf) – will create a PDF file based on generated report.

Attaching File
In general last step is optional and if you just want send report though email or save it somewhere you can skip it and do whatever you need, but in my case I just want to attach report to entity to not loose it and see result.

By the way you also can send this file for downloading right from memory (without saving to DB) by usage of PXRedirectToFileException with InMemory parameter and saving file to session by FileID

FileInfo file = new FileInfo(Guid.NewGuid(), "report.pdf", null, data);
PXContext.SessionTyped<PXSessionStatePXData>().FileInfo[file.UID.ToString()] = file;
throw new PXRedirectToFileException(file.UID, 0, true, true);

As a result you have report:

report PDF file acumatica

Full code snippet you can find here:

public class ARInvoiceEntry_Extension : PXGraphExtension<ARInvoiceEntry>
{
       #regionEvent Handlers
       public PXAction<PX.Objects.AR.ARInvoice> CreatePDF;

       [PXButton(CommitChanges = true)]
       [PXUIField(DisplayName = "Create PDF")]
       protected void createPDF()
       {
              //Report Paramenters
              Dictionary<String, String> parameters = new Dictionary<String, String>();
              parameters["ARInvoice.DocType"] = Base.Document.Current.DocType;
              parameters["ARInvoice.RefNbr"] = Base.Document.Current.RefNbr;

              //Report Processing
              PX.Reports.Controls.Report _report = PXReportTools.LoadReport("AR641000",null);
              PXReportTools.InitReportParameters(_report, parameters,
                      SettingsProvider.Instance.Default);
              ReportNode reportNode = ReportProcessor.ProcessReport(_report);

              //Generation PDF
              byte[] data = PX.Reports.Mail.Message.GenerateReport(reportNode, ReportProcessor.FilterPdf).First();
              FileInfo file = new FileInfo("report.pdf", null, data);

              //Saving report
              UploadFileMaintenance graph = new UploadFileMaintenance();
              graph.SaveFile(file);
              PXNoteAttribute.AttachFile(Base.Document.Cache, Base.Document.Current, file);

              //Downloading of the report
              throw new PXRedirectToFileException(file, true);
       }
       #endregion
}

Have a nice reporting!

29 Replies to “Get PDF file from Report using Code”

  1. Hi Sergey

    1) I am wondering does Acumatica have any built-in function to merge PDFs? If yes do you have any examples that you can share?

    2) If not is there a preferred third-party library that you can direct me to it. If it is your personal preference and not official from Acumatica is good enough for me.

    3) Is any built-in function to convert common file attachments types excel/word/tiff/jpg to pdf? Again, if not do you have any preferred/recommendation?

    1. Hi Alex,
      1) I’m not aware of any build in function to merge pdfs.
      2) Honestly, i’m not an expert here, probably need to experiment with this
      3) Unfortunately, the same answer. Probably we do not have such functions as part of the platform.
      I hear that some partners performed such customization to Acumatica, but I have no details.

    2. Hi Alex,

      If you are still looking at a way of merging, combining, splitting PDFs, ie merging multiples Invoices for a single Customer into one email and send ort archive. Liaison Messenger EDD can do that. You can also create rules based on the form/documents content and Messenger EDD can “read” the data from the PDF and then perform tasks like retrieve and insert/append/attach documents into the source document. Liaison Messenger is rules based, allowing you to create scripts (graphs) that is designed around a specific form/report.

      http://www.liaisonsc.com

      Call (800) 811-4618 x301 (Tom Nielsen) or email tom@liaisonsc.com
      Outside USA: (714) 543-9877

  2. The example in the original post works well for me in versions prior to 2021r2. But in 21r2, the compiler complains about obsolete PXReportTools and ReportProcessor methods.

    It’s not clear to me how to upgrade this for 21r2?

    1. Hi Josef,
      As far as I know currently there are no way to get report with rest. But possible with SOAP API

          1. Hi Sergey,

            I have followed your blog from here https://asiablog.acumatica.com/2017/07/getting-report-pdf-through-web-servies.html

            but 2019 R2 LinkCommand i can’t able to get the result.parameter.
            Command[] commands = new Command[]
            {
            new Value { Value = “9/1/2019”, LinkedCommand= schema.Result.Parameters.StartDate },
            new Value { Value = “9/1/2020”, LinkedCommand= schema.Result.Parameters.EndDate },
            new Value { Value = “ABARTENDE”, LinkedCommand= schema.Result.Parameters.CustomerID },
            schema.Result.ReportResults.PdfContent
            };

            do have any document for this. i have created support case as well.

            Thanks,
            Arun.

  3. Hi!
    I’m trying to execute my report but it has a subreport. How can I programatically execute my report with the subreport, and indicate the parameters to the subreport.
    If I execute manually the report works, but in the Action button, it seems like the subreport has no parameters

    1. Another thing that happens is that the pdf file, has 2 pages while executing manually the report is just one page.

      1. Hi Anahi, I’m really sorry but I cannot answer that question without an investigation. I recommend you to create a support case.

    2. Hi Anahi,
      As far as I know you can provide parameters only for top level report not for sub-reports. SubReports must have parameters from top level report.

  4. I am trying to get the report as XLSX file and everything is fine except that the report footer is missing (everything else, including page footer is in the right place). The PDF has the report footer, so does the Excel file exported from the web report.
    Any ideas about this issue?

    1. I recommend to create a Case for this problem. It looks for me as a bug more. Acumatica team should check this and fix if possible.

  5. Hi Sergey,

    How can i redirect to the file (open it in browser) without downloading it? Im using version 2019 R1.

    Thanks.

    1. Hi John, something like this may work for you
      public PXAction ViewRevisions;
      [PXUIField(DisplayName = ActionsMessages.Version)]
      [PXButton]
      protected IEnumerable viewRevisions(PXAdapter a)
      {
      UploadFile file = this.Files.Current;
      if (file == null)
      return a.Get();

      WikiFileMaintenance maint = PXGraph.CreateInstance();
      maint.Files.Current = maint.Files.Search(file.Name);
      throw new PXRedirectRequiredException(maint, “View Revisions”);
      }

  6. Julio,
    Make sure you are using correct version of .NET. You need to have 4.7.1 as .net not always can have reference from older version library to newer.

  7. Hello, when add reference, I get this message:

    Validating Binary Files
    PX.Reports.dll Failed to resolve method reference: System.Void PX.Reports.Barcode.QR.MatrixStatus[0…,0…]::.ctor(System.Int32,System.Int32) declared in PX.Reports.dll
    PX.Reports.dll Failed to resolve method reference: PX.Reports.Barcode.QR.MatrixStatus PX.Reports.Barcode.QR.MatrixStatus[0…,0…]::Get(System.Int32,System.Int32) declared in PX.Reports.dll
    PX.Reports.dll Failed to resolve method reference: System.Void PX.Reports.Barcode.QR.MatrixStatus[0…,0…]::Set(System.Int32,System.Int32,PX.Reports.Barcode.QR.MatrixStatus) declared in PX.Reports.dll
    Validation failed.

  8. Hi Julio,
    This PX.Reports.dll is included in Acumatica. Add reference to Acumatica Web Site/bin folder. It is located there.

  9. I mean this:
    Report
    To work with reports you need a reference to PX.Reports.dll, so make sure you have added it before compiling code below. To work with reports you can use PX.Reports.Controls.Report class there.

  10. Hi Unknown, i'm really sorry but I haven't fully understood your question. What libraries do you mean?

Leave a Reply

Your email address will not be published. Required fields are marked *