download.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. var express = require('express');
  2. var router = express.Router();
  3. const utils = require('../../libs/utils');
  4. const config = require('../../config/app');
  5. const { PDFDocument, rgb, StandardFonts } = require('pdf-lib');
  6. router.get('/pdf/:id', function (req, res, next) {
  7. (async function () {
  8. let id = req.params.id;
  9. utils.validators.validateId(id);
  10. let host = config.cdnHost ?? config.resHost;
  11. let url = `${host}/thumbs/coloring-page/page/1200/${id}.jpeg`;
  12. try {
  13. const response = await fetch(url);
  14. if (!response.ok) {
  15. throw new Error(`HTTP error! status: ${response.status}`);
  16. }
  17. const arrayBuffer = await response.arrayBuffer();
  18. const padding = 40;
  19. const pdfDoc = await PDFDocument.create();
  20. const page = pdfDoc.addPage();
  21. const image = await pdfDoc.embedJpg(arrayBuffer); // pdf-lib支持jpg,png
  22. // 获取图片原始尺寸
  23. const imageWidth = image.width;
  24. const imageHeight = image.height;
  25. // 计算带 padding 的图片绘制区域
  26. const pageWidth = page.getWidth();
  27. const pageHeight = page.getHeight();
  28. // 计算缩放比例,保证图片在带 padding 的区域内
  29. let scaledWidth = imageWidth;
  30. let scaledHeight = imageHeight;
  31. if (imageWidth + 2 * padding > pageWidth || imageHeight + 2 * padding > pageHeight) {
  32. const widthScale = (pageWidth - 2 * padding) / imageWidth;
  33. const heightScale = (pageHeight - 2 * padding) / imageHeight;
  34. const scale = Math.min(widthScale, heightScale);
  35. scaledWidth = imageWidth * scale;
  36. scaledHeight = imageHeight * scale;
  37. }
  38. // 计算图片绘制的起始坐标
  39. const x = (pageWidth - scaledWidth) / 2;
  40. const y = (pageHeight - scaledHeight) / 2;
  41. // 绘制图片,并留出 padding
  42. page.drawImage(image, {
  43. x: x,
  44. y: y,
  45. width: scaledWidth,
  46. height: scaledHeight,
  47. });
  48. const pdfBytes = await pdfDoc.save();
  49. res.setHeader('Content-Type', 'application/pdf');
  50. res.setHeader('Content-Disposition', `attachment; filename=${id}.pdf`);
  51. res.send(Buffer.from(pdfBytes));
  52. } catch (error) {
  53. console.error(`Error fetching image: ${id}`, error);
  54. }
  55. })().catch(next)
  56. });
  57. module.exports = router;