从ActiveReports / WebAPI

时间:2016-05-03 14:29:14

标签: c# angularjs pdf asp.net-web-api activereports

在我正在开发的项目中,我正在构建一个允许用户生成报告的功能 - 在我的情况下,它将根据我们数据库中存储的信息按需信封。我试图解决的问题是,正在生成一个空白的PDF。

我尝试过一些健全检查。首先,我在Visual Studio中设置了一个断点,并确保传递给报表的模型具有固定数据;报告是空白的。接下来,我尝试包含一个与任何数据无关的静态标签,以确定它是否是报告数据绑定问题 - 静态标签也没有出现在生成的报告中。

更令人困扰的是,我过去使用过类似的代码而没有问题。我不知道为什么在这种情况下会生成一个空白的PDF文件。

我已经阅读了StackOverflow提供的“类似问题”,特别是this question from one year ago,但它没有答案,因此无需向它学习。我也尝试过必要的谷歌搜索,但没有发现任何相关内容。

我唯一无法提供的是实际的ActiveReport本身。我已经为Silly Programmer Errors™检查了这一点,比如隐藏所有东西,透明标签或类似的傻事物。 不幸的是,我没有犯过这样的错误。

报告代码:

public partial class EnvelopeReport : SectionReport
{
    public EnvelopeReport()
    {
        InitializeComponent();
    }

    internal void RunReport(IEnumerable<PrintedAddress> model)
    {
        if (model != null)
        {
            DataSource = model;
        }

        Run();
    }

    private void OnReportStart(object sender, EventArgs e)
    {
        Document.Printer.PrinterName = string.Empty;
        PageSettings.PaperKind = PaperKind.Number10Envelope;

        PageSettings.Margins.Top = 0.25f;
        PageSettings.Margins.Left = 0.5f;
        PageSettings.Margins.Right = 0.5f;
        PageSettings.Margins.Bottom = 0.25f;
    }
}

Web API控制器代码:

    [HttpGet]
    public HttpResponseMessage EnvelopeReport(int addressId, string attentionTo, bool isConfidential)
    {
        Address address = AddressRepository.GetAddress(addressId, true);
        List<PrintedAddress> models = new List<PrintedAddress>
        {
            new PrintedAddress(address, attentionTo, isConfidential)
        };

        var report = new EnvelopeReport();
        report.RunReport(models);

        var pdfExporter = new ActiveReportsPdfExporter();
        var reportBytes = pdfExporter.ExportPdf(report);

        var response = Request.CreateResponse(HttpStatusCode.OK);
        response.Content = new ByteArrayContent(reportBytes, 0, reportBytes.Length);
        response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
        {
            FileName = "Envelope Report.pdf"
        };

        return response;
    }

PDF导出器:

public class ActiveReportsPdfExporter
{
    private readonly PdfExport _pdfExport;

    public ActiveReportsPdfExporter()
    {
        _pdfExport = new PdfExport();
    }

    public byte[] ExportPdf(SectionReport report)
    {
        using (var stream = new MemoryStream())
        {
            _pdfExport.Export(report.Document, stream);
            return stream.ToArray();
        }
    }

    public Stream ExportPdfToStream(SectionReport report)
    {
        var stream = new MemoryStream();
        _pdfExport.Export(report.Document, stream);
        return stream;
    }
}

客户服务(Angular):

(function () {
    angular.module('app').factory('addressSvc', [
        '$http', addressSvc
    ]);

    function addressSvc($http) {
        var service = {
            printAddress: function(addressId, attentionTo, someFlag) {
                var args = {
                    'addressId': thingId,
                    'attentionTo': attentionTo,
                    'isConfidential': isConfidential
                };

                return $http.get('/api/common/EnvelopeReport', { 'params': args });
            }
        };

        return service;
    }
})();

客户端控制器(Angular):

(function() {
    angular.module('app').controller('someCtrl', [
        '$window', 'addressSvc', controller
    ]);

    function controller($window, addressSvc) {
        var vm = this;
        vm.attentionTo = '';    // Bound to UI.
        vm.isConfidential = ''; // Also bound to UI.
        vm.address = {};        // Unimportant how we get this.
        vm.printAddress = printAddress;

        function printAddress() {
            addressSvc.printAddress(vm.address.id, vm.attentionTo, vm.isConfidential)
                .then(function(result) {
                    var file = new Blob([result], {type: 'application/pdf'});
                    var fileURL = URL.createObjectURL(file);

                    if(window.navigator && window.navigator.msSaveOrOpenBlob) {
                        window.navigator.msSaveOrOpenBlob(file, 'Envelope.pdf');
                    } else {
                        $window.open(fileURL);
                    }
                });
        }
    }
)();

问题:为什么此代码会生成空PDF?我过去成功地使用了Report / API Controller结构来生成PDF,但通常是在MVC的上下文中,而不是Web API。另一个潜在的失败点是客户端代码 - 我之前没有以这种方式在服务器和客户端之间传递报告。

1 个答案:

答案 0 :(得分:0)

因此,事实证明我的服务器端代码完全正确。客户端代码已关闭。

而不是Blobbing从服务器返回的数据和所有这些工作,我需要做的是构建一个URL ...并调用$window.open(url);这是因为我的服务器代码将返回PDF文件按原样。