download.js 2.4 KB

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