AngularJS,从缓冲区响应中的PDF开放预览
我正在使用nodejs 16.4
和angularjs 1.5.8
。我还使用JSReport
( jsreport )和nodejs Integration。
这是我的任务:我需要通过使用JSReport的模板创建PDF。我做到了,该功能正在生成缓冲区响应
:
router.post('/queryreport/certificationAdvancement', async function(req, res) {
try {
const data = req.body.data;
var inspectionType = '';
if(data.inspection == 12) inspectionType = 'Ispezioni Visive';
else inspectionType = `Ispezioni ${data.supervision_number}^ Sorveglianza`;
const title = 'Stato Avanzamento delle Certificazioni';
const subtitle = `${inspectionType} - Anno ${data.year}`;
//Header del Report
const header = await get_queryReport_header(data.dealer, title, subtitle);
//Footer del Report
const footer = await get_footer(title);
//Dataset del Report
const dataset = await get_certificationAdvancement_dataset(data);
//Costruzione del Report tramite JSReport
const report = await jsreport.render({
template: {name: 'certificationAdvancement'},
data: {header: header, dataset: dataset, footer: footer}
})
const buffer_report = await report.body();
console.log(buffer_report);
res.contentType('application/pdf');
res.send(buffer_report);
}
catch (error) {
global.loggerWinston.error(commons.sios_loggerWinstonError(error, 'SIOS'));
return commons.showerror(error, res);
}
});
console.log(Buffer_Report)
具有缓冲区的形式:<缓冲区25 50 44 46 2d 31 2e 36 0a 25 ff ff ff ff ff ff ff 0a 34 20 30 20 30 20 6f 62 62 6a 0a 3c 3c 3c 3c 3c 3c 0a 0 a 09 2f 63 61 20 31 0a 09 310a 09 2f 42f 42f 42 f 42 f 42 f 42 f 4 e 61 6C 0A 3E 3E 0A ... 38478更多字节>
我试图将其发送回前端(AngularJS),并在浏览器内预览PDF文件,可能是在新的选项卡中。我尝试了许多解决方案,但似乎没有什么
$scope.download_jsreport = function () {
var data = {year: $scope.Year, dealer: $scope.Dealer, inspection: parseInt($scope.Inspection)};
if($scope.numSorv) data.supervision_number = $scope.numSorv;
/*
jsreportService.certificationAdvancement.post is the service used to call the function
I could write it through a $http.post like this
$http.post('/api/jsreport/queryreport/certificationAdvancement', {data: data})
.then(function(result) {
});
*/
//$window.open(jsreportService.certificationAdvancement.post({data: data}), '_blank');
jsreportService.certificationAdvancement.post({data: data}, function (result) {
/* var a = document.createElement("a");
a.href = "data:application/octet-stream;base64," + encodeURIComponent(result.report);
a.target = "_blank";
a.download = result.filename;
document.body.appendChild(a);
a.click();
var a_link = document.createElement('a');
a_link.href = 'data: application/octet-stream; base64, ' + result.buffer_report.data;
a_link.download = 'certificationAdvancement.pdf';
a_link.click(); */
});
}
建议吗?
编辑: 根据Michael G.的回答,我设法解决了它。
这是服务器端调用的最后一部分,当PDF已经完成时(上一部分保持不变)
//Costruzione del Report tramite JSReport
const report = await jsreport.render({
template: {name: 'certificationAdvancement'},
data: {header: header, dataset: dataset, footer: footer}
});
const resultReport = await report.body();
return res.send(Buffer.from(resultReport).toJSON());
,并且控制器部件变为(呼叫完成后):
const reportBuffer = new Uint8Array(result.data);
const file = new Blob([reportBuffer], {type: 'application/pdf'});
const fileURL = window.URL.createObjectURL(file);
const fileName = 'file.pdf';
var a_link = document.createElement('a');
document.body.appendChild(a_link);
a_link.style = 'display: none';
a_link.href = fileURL;
a_link.download = fileName;
a_link.click();
I'm using NodeJS 16.4
and AngularJS 1.5.8
. I'm also using JSReport
(JSReport) with NodeJS integration.
This is my task: i need to create a pdf through a template with JSReport. I did it and the function is generating a buffer response
:
router.post('/queryreport/certificationAdvancement', async function(req, res) {
try {
const data = req.body.data;
var inspectionType = '';
if(data.inspection == 12) inspectionType = 'Ispezioni Visive';
else inspectionType = `Ispezioni ${data.supervision_number}^ Sorveglianza`;
const title = 'Stato Avanzamento delle Certificazioni';
const subtitle = `${inspectionType} - Anno ${data.year}`;
//Header del Report
const header = await get_queryReport_header(data.dealer, title, subtitle);
//Footer del Report
const footer = await get_footer(title);
//Dataset del Report
const dataset = await get_certificationAdvancement_dataset(data);
//Costruzione del Report tramite JSReport
const report = await jsreport.render({
template: {name: 'certificationAdvancement'},
data: {header: header, dataset: dataset, footer: footer}
})
const buffer_report = await report.body();
console.log(buffer_report);
res.contentType('application/pdf');
res.send(buffer_report);
}
catch (error) {
global.loggerWinston.error(commons.sios_loggerWinstonError(error, 'SIOS'));
return commons.showerror(error, res);
}
});
The console.log(buffer_report)
has the form of a buffer:<Buffer 25 50 44 46 2d 31 2e 36 0a 25 ff ff ff ff 0a 0a 34 20 30 20 6f 62 6a 0a 3c 3c 0a 09 2f 63 61 20 31 0a 09 2f 42 4d 20 2f 4e 6f 72 6d 61 6c 0a 3e 3e 0a ... 38478 more bytes>
I'm trying to send it back to front end (angularJS) and preview the pdf file inside the browser, possibly in a new tab. I've tried many solutions but it seems nothing's working
$scope.download_jsreport = function () {
var data = {year: $scope.Year, dealer: $scope.Dealer, inspection: parseInt($scope.Inspection)};
if($scope.numSorv) data.supervision_number = $scope.numSorv;
/*
jsreportService.certificationAdvancement.post is the service used to call the function
I could write it through a $http.post like this
$http.post('/api/jsreport/queryreport/certificationAdvancement', {data: data})
.then(function(result) {
});
*/
//$window.open(jsreportService.certificationAdvancement.post({data: data}), '_blank');
jsreportService.certificationAdvancement.post({data: data}, function (result) {
/* var a = document.createElement("a");
a.href = "data:application/octet-stream;base64," + encodeURIComponent(result.report);
a.target = "_blank";
a.download = result.filename;
document.body.appendChild(a);
a.click();
var a_link = document.createElement('a');
a_link.href = 'data: application/octet-stream; base64, ' + result.buffer_report.data;
a_link.download = 'certificationAdvancement.pdf';
a_link.click(); */
});
}
Any suggestion?
EDIT:
based on Michael G.'s answer, I managed to resolve it.
This is the final part of the server-side call, when the pdf is already done (the previous part remained the same)
//Costruzione del Report tramite JSReport
const report = await jsreport.render({
template: {name: 'certificationAdvancement'},
data: {header: header, dataset: dataset, footer: footer}
});
const resultReport = await report.body();
return res.send(Buffer.from(resultReport).toJSON());
And the controller part became (when the call is done):
const reportBuffer = new Uint8Array(result.data);
const file = new Blob([reportBuffer], {type: 'application/pdf'});
const fileURL = window.URL.createObjectURL(file);
const fileName = 'file.pdf';
var a_link = document.createElement('a');
document.body.appendChild(a_link);
a_link.style = 'display: none';
a_link.href = fileURL;
a_link.download = fileName;
a_link.click();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是我整个星期都在尝试做的事情。这是我发现的解决方案,似乎可以按照应有的方式工作:
在将报告缓冲区数据从Express返回到AngularJS时,我将缓冲区转换为JSON,
因为在Express侧,我将.DATA从JSON格式化的缓冲区转换为Uint8array:
在这种情况下,也应适用于HTML 。
This has been something I've been trying to do all week. This is the solution I've found that seems to work the way it should:
When returning the report buffer data from Express to AngularJS I convert the buffer to JSON as:
On the Express side, I convert the .data from the JSON formatted buffer to an Uint8Array:
In this case, PDF, but should work for HTML as well.