【问题标题】:How can I print a PDF client side that was received from my server?如何打印从我的服务器收到的 PDF 客户端?
【发布时间】:2022-05-06 23:54:50
【问题描述】:

所以我对从服务器端生成 PDF 非常陌生,因为我通常总是从客户端创建它们。我决定迁移到严格地在服务器端创建它们,因为我相信这样做有更大的灵活性。我最近一直在努力解决的一件事是,我正在尝试从服务器生成 PDF,然后在客户端检索数据并能够从那里打印。

我正在使用pdfmake 库在服务器上生成我的PDF。您可以在此处看到我正在使用 get 请求来检索生成的 PDF:

server.get(`/api/print_paper_letter`, bodyParser.urlencoded({extended: false}), async (req,res) => {
            try {
                const doc = await PrintPaperLetter(req.body.pdf_obj);
                res.type('application/pdf');
                res.send(doc);
            } catch (e) {
                console.error(`api.print_paper_letter: ${e}`);
                res.sendStatus(400);
            }
        });

我在这里从另一个文件生成 PDF:

PrintLetter.js

const PdfPrinter = require('pdfmake');
import {PaperLetterNormal} from '../../components/PDFTemplates';

const fonts = {
    Helvetica: {
        normal: 'Helvetica',
        bold: 'Helvetica-Bold',
        italics: 'Helvetica-Oblique',
        bolditalics: 'Helvetica-BoldOblique'
      }
}

export const PrintPaperLetter = async (pdf_obj) => {
    return new Promise(async(resolve,reject) => {
        try {
            const printer = new PdfPrinter(fonts);
            const definition = PaperLetterNormal(pdf_obj);
            const pdf = printer.createPdfKitDocument(definition);
            let chunks = [];
            pdf.on('data', chunk => chunks.push(chunk));
            pdf.on('end',() => resolve(Buffer.concat(chunks)));
            pdf.end();
        } catch (e) {
            console.error(`PaperLetters.PrintPaperLetter: ${e}`);
            reject(e);
        }
    })
}

当我调用从客户端检索 PDF 数据时,我最终得到了某种垃圾数据,但我不确定如何打印这些数据。

客户端代码:

const pdf_obj = {
  .
  .
  .
}

$.post('/api/print_paper_letter',{pdf_obj: pdf_obj},(res) => {
                    if(!res){
                        console.error(`there was an issue retrieving this pdf doc`)
                    }else{
                        console.log({res});
                    }
                })

客户端的响应如下所示:

%PDF-1.3
%ÿÿÿÿ
9 0 obj
<<
/Type /ExtGState
/ca 1
/CA 1
>>
endobj
11 0 obj
<<
/Type /ExtGState
/CA 1
>>
endobj
13 0 obj
<<
/Type /ExtGState
/ca 1
>>
endobj
8 0 obj
<<
/Type /Page
/Parent 1 0 R
/MediaBox [0 0 595.28 841.89]
/Contents 6 0 R
/Resources 7 0 R
>>
endobj
7 0 obj
<<
/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
/ExtGState <<
/Gs1 9 0 R
/Gs2 11 0 R
/Gs3 13 0 R
>>
/XObject <<
/I1 5 0 R
>>
/Font <<
/F1 10 0 R
/F2 12 0 R
>>
>>
endobj
6 0 obj
<<
/Length 2896
/Filter /FlateDecode
>>
stream
xÍ]ÛrÇ
}߯P»ÑúR¥âíÄ?¤*±Þ\~Ë\*J*QUòû9îλ i.d¦¤
û hà}M_ï¿t¡ÔÇ´ý¼ùæ/4ýåËæßÒ¼GjCõIòÔìå?Ðôý¿6:üÔ7ßïþû·íîÏ?|;m¿lö?ÿeûÏÍÝ3Þâ9¾ý°<§^8uÜËôø¿§òôánóó{V|ço¦üËôáÇÍï><K²§q«¦\h¥¦êmô4;ÐB76,ï[½Nï«ÞLßËîfªx QMâ
ìD#pSjMjºöT«gÄ
Ö·Àî9=ÑqT8ÉSømkÇк
ÂÁ5º[ÙEà*§ª¾ÛQf¨¾^[2§æ@·ù¿Eí;-üû1´rco½¯Ù0ê]ÝÛë×%ëRCgëØA-¾[&Þ,5þâ®ÊV¦ÿm~þ·èïøþqGYÉx>o´éúÁ?Öýøî§¥?}÷Gëg±~þtu­{Q×#FÃÞÛô÷ÎÜ8'.ÍÅûn%
­H·GüÖÂ\Íh©UrÄáÂãcÕÈÂ
þÐ_ͬ0¯ÒhtNÝhA²¡Zêà+Û4[ÉI{½oÀS¬w{jÔê>Z·«In©IÆ÷Ð%m%Bà\/K á°#»&xHù¤£;¸QùãͤQláwª§ó¬æy2é[RÎ]ÏûVBèt­x¦¶
{D¼kOàÂOô°nà´Þâ{â1IGêÅ%9æãahÁzº¯{Æ'!@É5isû?öá2ÌËbB§n³þ²f39F´ÚÕ!D'¸Üñ[Ù\j,P³Äj ­ÙÝÏxëÇígD§2rÐIñé|¶å'Ë´ î§kÁÉpÑ©ÊóÉìH0p××XoìÉ¡yºÝ\?`UJ¤Ýë¿´ÉX®æD|dν5$I˹ßþ°:GüÒEgÒ;0qfIª0HdRÏLa(bÌä0Ý*%Ñîàòg¹
¨~!U-ÕÞ²®ï
.
.
.

如果有人可以根据响应向我解释我正在查看的内容,并且可以将其转换为然后在客户端打印它,那将是惊人的。如果您需要我在我的帖子中添加更多内容,请告诉我。蒂亚!

【问题讨论】:

    标签: node.js express pdfmake


    【解决方案1】:

    当您发送 pdf 响应时,您正在向前端发送一个 blob/缓冲区,因此您需要在前端捕获它以显示/下载内容。

    如果您想立即提示下载,请将res.attachment(filename) 添加到您的 express 函数中。

    解释:

    res.attachment() 与本机节点 response.setHeader() 命令相同。它将content-disposition 标头属性设置为attachment,另外设置文件名(如果提供的话)。
    之后,要实际提供文件,您需要调用 res.send() 方法来结束进程并发送响应,就像处理任何请求一样。

    或者,如果您想在客户端呈现文件,则需要使用兼容元素,例如(相对较新的)HTML object,或其他兼容元素。

    【讨论】:

    • 感谢您的意见。我将尝试快速解决方案,看看是否有效。
    • 我尝试将 res.attachment(doc) 添加到我的 express 方法中,但它给了我一个错误,说“路径”参数必须是字符串类型。考虑到我没有将此文档保存为静态文件,我认为这不会起作用,而是我只是生成它,然后将其传递给客户端以接收。
    • “路径”只是一个文档名,不一定是实际的文件路径。见here
    • 好的,谢谢。那么在调用attachment 之后,我还要调用res.send(doc) 吗?还是 express 已经知道我传递的数据?
    • 好的,所以我目前正在做res.attachment('./test_pdf.pdf') 然后res.send(doc),但没有下载。我没有收到任何错误,这意味着它必须工作,但我可以在任何地方看到该文件。
    猜你喜欢
    • 1970-01-01
    • 2011-11-06
    • 1970-01-01
    • 2017-09-19
    • 1970-01-01
    • 2013-10-25
    • 1970-01-01
    • 1970-01-01
    • 2021-02-15
    相关资源
    最近更新 更多