Populating a PDFKit Image from Firebase Storage while in a Firebase Function?
我一直在尝试从PDFKit中填充PDFDoc中的图像,但无法使其正常工作。使用以下功能时,Firebase控制台功能日志中会出现以下错误。该文件以" image / png"类型存储在Firebase Storage中。名称只是一个字符串。我尝试在名称后附加" .PNG",但收到相同的错误。我包含了整个函数文件,因为也许有一种更可接受的方式来处理此问题?在使用Firebase功能时,如何从Firebase存储中将PDF插入PDFDoc?谢谢。
获取文档时出错:错误:图像格式未知。
在Function.PDFImage.open(/user_code/node_modules/pdfkit/js/image.js:43:15)
在PDFDocument.openImage(/user_code/node_modules/pdfkit/js/mixins/images.js:102:26)
在PDFDocument.image(/user_code/node_modules/pdfkit/js/mixins/images.js:30:24)
在/user_code/lib/index.js:71:48
在QuerySnapshot.forEach(/user_code/node_modules/firebase-admin/node_modules/@google-cloud/firestore/src/reference.js:1012:16)
在/user_code/lib/index.js:24:31
在process._tickDomainCallback(内部/进程/next_tick.js:135:7)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | import * as functions from 'firebase-functions'; import * as admin from 'firebase-admin'; import * as firebase from 'firebase/app'; import * as PDFDocument from 'pdfkit'; admin.initializeApp(functions.config().firebase); export const genPdf = functions.https.onRequest((request, response) => { const bucket = admin.storage().bucket("decteac2-3hcec.appspot.com"); const text = request.query.text; const pdfdoc = new PDFDocument({ autoFirstPage: false }); pdfdoc.info['Title'] = text +".pdf"; let x = 5; let y = 5; pdfdoc.pipe(response); const docRef = admin.firestore().collection("cxforms").doc(text); docRef.get().then(function (doc) { if (doc.exists) { const pagesRef = admin.firestore().collection("pages").where("formKey","==", text).orderBy("pageno"); pagesRef.get().then(function (querySnapshot) { let cnt = 1; querySnapshot.forEach(function (page) { pdfdoc.addPage({ margin: 0 }); x = 5; y = 5; pdfdoc.moveTo(x, y) .lineTo(607, 5) .lineTo(607, 787) .lineTo(5, 787) .lineTo(x, y) .stroke(); for (let i = 0; i < page.data().tables.length; i++) { const table = page.data().tables[i]; y = y + 8.5; // margin var tableWidth = 5; for (let p = 0; p < table.cols.length; p++) { tableWidth = tableWidth + (table.cols[p] * .82); } var offset = (597 - tableWidth) / 2; for (let j = 0; j < table.rows.length; j++) { const row = table.rows[j]; x = 10 + offset; for (let k = 0; k < row.cells.length; k++) { const cell = row.cells[k]; const colwidth = table.cols[k]; var height = 22.2; for (let l = 0; l < cell.cellels.length; l++) { const cellEl = cell.cellels[l]; if (cellEl.type ==="Text") { pdfdoc.text(cellEl.text, x + 1, y + 7); } else if (cellEl.type =="Image") { const filename = cellEl.storageid; const file = bucket.file(filename); const bucketFileStream = file.createWriteStream(); const buffer = new Buffer([1000000]); bucketFileStream.write(buffer); bucketFileStream.end(); pdfdoc.image(buffer, x, y); } } if (height < 20) { height = 20; } pdfdoc.moveTo(x, y) .lineTo(x + (colwidth * .82), y) .lineTo(x + (colwidth * .82), y + height) .lineTo(x, y + height) .lineTo(x, y) .stroke(); x = x + (colwidth * .82); } y = y + height; } } cnt++; }); pdfdoc.end(); }).catch(function (error) { console.log("Error getting documents:", error); }) } else { console.log("No such document!"); } }).catch(function (error) { console.log("Error gettting documents:", error); }); }); |
这就是我如何解决这个问题的方法。关键项目是将响应编码设置为" base64"以调用Firestorage。另一个项目正在使用async和await,以便等待每个单元格元素图像填充pdfdoc,然后再继续下一个要呈现的单元格元素。
if(cellEl.type ==" Image"){等待toBase64(cellEl.url,x,y,pdfdoc);}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | function toBase64(url, x, y, pdfdoc) { return new Promise(async(resolve, reject) => { var req = await https.get(url, (res) => { res.setEncoding('base64'); let body ="data:" + res.headers["content-type"] +";base64,"; res.on('data', (d) => { body += d; }); res.on('end', () => { pdfdoc.image(body, x, y); resolve(res); }); }); req.on('error', err => { console.error('error!'); reject(err); }); }); } |