【微信小程序云开发】使用云函数(node.js)实现多张图片转成pdf的功能,且pdf带水印

最近在做项目的时候,碰到一个功能需要多张图片转成pdf的功能,首先,在网上找了很多资料,都没有一个合适的。

后来,就自己动手使用云函数写了一个处理图片转成pdf的云函数,而且需带水印。

直奔主题,使用的是微信小程序云开发里面的云函数,是基于node.js写的

先看效果:

在这里插入图片描述

看完整代码,都有详细注释!!!

// 云函数多张图片 转成 pdf 
//引入模块之前,记得先install安装模块哈,熟悉nodejs的安装模块不难,不懂的百度一下
const cloud = require('wx-server-sdk');
const { PDFDocument, StandardFonts, rgb } = require('pdf-lib');  //引入pdf-lib模块,转成pdf的时候用到
const {fontkit} = require('@pdf-lib/fontkit')    //引入@pdf-lib/fontkit模块,水印的时候用到

cloud.init({
  env:'你的环境id'  //填入你的环境id
});

// 云函数入口函数
exports.main = async (event, context) => {
    //接收小程序端传来的图片数组
    let img_arr  =event.img_arr;
    //arr是用来存储fileContent的数组
    let arr = []
    //pdf的总高度,是等于数组里面的所有图片的高度之和
    let zheight = 0
    //用来存储处理过后的各个图片信息的数组
    let content_arr = []

    const doc = await PDFDocument.create();
    let page = doc.addPage();
    doc.registerFontkit(fontkit)
    
    //下载图片 获取fileContent,并且存入arr数组
    for (let i = 0; i < img_arr.length; i++) {
      let lian = img_arr[i]
      let lenderSignSign = await cloud.downloadFile({
        fileID:lian
      });
      //concat是数组直接的拼接,这里需要使用push,这是个开发习惯导致的坑
      arr.push(lenderSignSign.fileContent)          
    }

    //获取所有照片组成的高度和宽度
    for (let j = 0; j < arr.length; j++) {
          //判断图片是png
          if(img_arr[j].match(/.png/g)){
            let img = await doc.embedPng(arr[j]);
            //计算图片展示的宽高,根据原有的比例和pdf的宽度来算
            let h = (img.height*700)/img.width
            let obj ={
              img:img,
              width:700,
              height:h,
            }
            content_arr.push(obj)
            zheight =parseInt(zheight + h)
          }
          //判断图片是jpg
          if(img_arr[j].match(/.jpg/g)){
            let img = await doc.embedJpg(arr[j]);
            //计算图片展示的宽高,根据原有的比例和pdf的宽度来算
            let h = (img.height*700)/img.width
            let obj ={
              img:img,
              width:700,
              height:h,
            }
            content_arr.push(obj)
            zheight =parseInt(zheight + h)
          }
          //判断如果图片不是png或者jpg。则返回提示
          if(!img_arr[j].match(/.jpg/g)&&!img_arr[j].match(/.png/g)){
                let str = '图片只支持jpg和png格式'
                return str
          }
    }

    //开始设置pdf的高度和宽度
    page.setWidth(800);
    page.setHeight(zheight);

    //guodu_height用来存储排在前面的高度
    let guodu_height = 0
    //开始绘制
    for (let i = 0; i < content_arr.length; i++) {
      guodu_height = guodu_height + content_arr[i].height
      let height = zheight - guodu_height
      page.drawImage(content_arr[i].img,{
        x: 50,           //左右各间隔50
        y: height
        ,width:content_arr[i].width
        ,height:content_arr[i].height,
      });
    }

    // 定义水印的字体
    const customFont = await doc.embedFont(StandardFonts.Helvetica)
    // 定义水印,水印不能中文,不然会报错
    const text = 'this is ziwenlu'
    const textSize = 20
    // 嵌入水印
    page.drawText(text, {
      x: 0,
      y: 0,
      size: textSize,
      font:customFont,
      opacity: 0.5,
      color: rgb(0, 0.53, 0.71),
    })

    const docBase64 = await doc.saveAsBase64()
    const docBuffer = Buffer.from(docBase64, 'base64');
    //表明这个pdf是存放在云存储里面带的tmp文件夹,后面是给pdf取名称
    let fileName = 'tmp/' + parseInt(new Date().getTime() / 1000) + '.pdf';
    //开始上传到云存储
    let result = await cloud.uploadFile({ cloudPath: fileName, fileContent: docBuffer });
    let fileID = result.fileID;
    //转http访问
    const fileList = await cloud.getTempFileURL({
      fileList: [fileID],
    });
    let pdf = fileList.fileList[0].tempFileURL;
    return { code: 1, msg: '', data: { fileID: fileID, pdf: pdf } }

}

这就是完整的云函数代码。不过这个处理有点点耗时,再加上云函数的冷启动缺点,云函数的请求超时时间默认是3秒,所以建议把云函数的请求超时时间改为10秒,这样就不会请求超时了,测试过还是挺快的。

end

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值