Supongamos que he creado un informe con Acumatica Report Designer y está vinculado al DAC relevante.

También tengo una pantalla personalizada con una acción. Cuando el usuario ejecuta esta acción, quiero generar el informe para que el usuario lo descargue como pdf.

¿Cuál es el enfoque para generar el informe como PDF mediante programación a través de la API de Acumatica?

0
Joseph Caruana 14 ene. 2018 a las 19:56

3 respuestas

La mejor respuesta

Consulte el fragmento de código a continuación para ver un ejemplo que muestra cómo generar un informe mediante programación como archivo PDF y mostrar SaveFileDialog para descargar / guardar el PDF generado:

public PXAction<IOITInboundTestWorkOrder> GenerateReportAndRedirectToFile;
[PXButton]
[PXUIField(DisplayName = "Generate Report and Download as PDF")]
protected void generateReportAndSaveToDB()
{
    Actions.PressSave();
    PXLongOperation.StartOperation(this, () =>
    {
        PX.SM.FileInfo file = null;
        using (Report report = PXReportTools.LoadReport("SO641012", null))
        {
            var orderNbr = ITWO.Current.OrderNbr;
            if (report == null) throw new Exception("Unable to access Acumatica report writter for specified report : " + "SO641012");
            Dictionary<string, string> prams = new Dictionary<string, string>();
            prams["ITWONbr"] = orderNbr;
            PXReportTools.InitReportParameters(report, prams, PXSettingProvider.Instance.Default);
            ReportNode repNode = ReportProcessor.ProcessReport(report);
            IRenderFilter renderFilter = ReportProcessor.GetRenderer(ReportProcessor.FilterPdf);

            using (StreamManager streamMgr = new StreamManager())
            {
                renderFilter.Render(repNode, null, streamMgr);
                string fileName = string.Format("Inbound Test Work Order #{0}.pdf", orderNbr);
                file = new PX.SM.FileInfo(fileName, null, streamMgr.MainStream.GetBytes());
            }
        }
        if (file != null)
        {
            throw new PXRedirectToFileException(file, true);
        }
    });
}
1
RuslanDev 15 ene. 2018 a las 02:13

Si no desea tratar de exponer la URL, el método aceptado parece ser invocar un método para almacenar el archivo en el registro de Acumatica y luego recuperar el archivo a través de la API: Obtenga la salida del informe en PDF fromat a través de Acumatica REST API

1
June B 25 oct. 2018 a las 17:09

Tuve problemas con la respuesta aceptada ya que estoy usando la API REST y, por alguna razón, PXRedirectToFileException funciona allí (no devuelve un encabezado de ubicación). Se me ocurrió esta solución realmente torpe que hace que la URL del archivo se exponga en una excepción. Perdona mi grosero nombre de excepción. :-)

using SiteStatus = PX.Objects.IN.Overrides.INDocumentRelease.SiteStatus;
using System.Linq;
using PX.Common;
using CRLocation = PX.Objects.CR.Standalone.Location;
using PX.Objects.AR.CCPaymentProcessing;
using PX.Objects.AR.CCPaymentProcessing.Common;
using PX.Objects.AR.CCPaymentProcessing.Helpers;
using PX.Objects.Common;
using PX.Objects;
using PX.Objects.SO;
using PX.Reports;
using PX.Reports.Data;
using PX.Data.Reports;
using PX.SM;

namespace PX.Objects.SO
{

  public class SOInvoiceEntry_Extension:PXGraphExtension<SOInvoiceEntry>
  {

    #region Event Handlers
    protected virtual void ARInvoice_RowSelected(PXCache cache, PXRowSelectedEventArgs e){
        CreateInvoicePDF.SetEnabled(true);
    }

     public PXAction<ARInvoice> CreateInvoicePDF;
     [PXButton]
     [PXUIField(DisplayName = "Create Invoice PDF", Enabled = true, Visible = false)]
     public virtual void createInvoicePDF()
     {
            //Report Paramenters
            Dictionary<String, String> parameters = new Dictionary<String, String>();
            parameters["DocType"] = Base.Document.Current.DocType;
            parameters["RefNbr"] = Base.Document.Current.RefNbr;

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

            // Generate PDF
            byte[] data = PX.Reports.Mail.Message.GenerateReport(reportNode, ReportProcessor.FilterPdf).First();
            FileInfo file = new FileInfo(Guid.NewGuid(), "Invoice" + Base.Document.Current.RefNbr + ".pdf", null, data);

            // Store data in session
            PXContext.SessionTyped<PXSessionStatePXData>().FileInfo[file.UID.ToString()] = file;

            // Include file URL in exception. The client will parse the filname and fetch the URL in a subsequent request.
            PXRedirectToFileException e =  new PXRedirectToFileException(file.UID, 0, true, true);

            string url = e.Url;

            throw new AcumaticaIsFullOfShitException(url);
     }

    #endregion

    }

    class AcumaticaIsFullOfShitException : PXException {
        public AcumaticaIsFullOfShitException(string message) : base(message) {

        }
    }

}

La desventaja es que esta acción solo se puede usar a través de la API. Agregué la acción al punto final de servicios web. En el otro extremo, utilicé regex para extraer la cadena del mensaje de excepción y realicé una solicitud de obtención para recuperar el archivo.

-1
micwallace 24 sep. 2018 a las 01:18
48251944