在我正在开发的项目中,我正在构建一个允许用户生成报告的功能 - 在我的情况下,它将根据我们数据库中存储的信息按需信封。我试图解决的问题是,正在生成一个空白的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。另一个潜在的失败点是客户端代码 - 我之前没有以这种方式在服务器和客户端之间传递报告。
答案 0 :(得分:0)
因此,事实证明我的服务器端代码完全正确。客户端代码已关闭。
而不是Blobbing从服务器返回的数据和所有这些工作,我需要做的是构建一个URL ...并调用$window.open(url);
这是因为我的服务器代码将返回PDF文件按原样。