AngularJS,从缓冲区响应中的PDF开放预览

发布于 2025-02-09 04:31:01 字数 4024 浏览 2 评论 0原文

我正在使用nodejs 16.4angularjs 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

丢了幸福的猪 2025-02-16 04:31:01

这是我整个星期都在尝试做的事情。这是我发现的解决方案,似乎可以按照应有的方式工作:
在将报告缓冲区数据从Express返回到AngularJS时,我将缓冲区转换为JSON,

res.send(Buffer.from(report.content).toJSON());

因为在Express侧,我将.DATA从JSON格式化的缓冲区转换为Uint8array:

let reportBuff = new Uint8Array(reportOutput.data);
let pageData = new Blob([reportBuff], {type: 'application/pdf'} );
this.$window.open(URL.createObjectURL(pageData));

在这种情况下,也应适用于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:

res.send(Buffer.from(report.content).toJSON());

On the Express side, I convert the .data from the JSON formatted buffer to an Uint8Array:

let reportBuff = new Uint8Array(reportOutput.data);
let pageData = new Blob([reportBuff], {type: 'application/pdf'} );
this.$window.open(URL.createObjectURL(pageData));

In this case, PDF, but should work for HTML as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文