前端生成指定大小的pdf文件

1,628 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

地址戳这里github地址,欢迎star

背景

在某一天开发完了pdf文件上传功能后,想自己测试一下文件大小限制功能是否生效,于是开始在网上找满足要求的pdf文件。

结果花了很长的时间,才找到(看来搜索技艺还不够精通)...

于是开始想能不能做一个根据输入的数字大小,来生成对应大小的pdf文件的功能。

分析需求

要生成文件?那用node吧,可以读写文件...可是我又没服务器放node程序...那不如用electron?不行,太麻烦了,还得下载客户端,能不能用个网页纯前端直接实现?在用尽了我几十年的搜索功力下= =,功夫不负有心人,终于找到了一个库pdfjs。

实现

主要代码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>生成指定大小pdf(有一定误差)</title>
  </head>
  <body>
    <div>
      <h2>PDF</h2>
      <input
      style="width: 190px;"
        type="number"
        id="pdfSize"
        oninput="this.value = this.value.replace(/[^0-9]/g, '');"
        placeholder="请输入正整数(单位:M)"
      />
      <button onclick="createPdf()">生成pdf</button>
    </div>
  </body>
  <script src="./jspdf.min.js"></script>
  <script>
    // 生成pdf的方法
    function createPdf() {
      const size = document.querySelector("#pdfSize");
      const designSize = parseFloat(size.value || 0) * 1024 * 1024// 设计大小字节
      if (isNaN(designSize) || designSize === 0) {
        alert("请输入正整数!");
        return;
      }
      const defaultSize = 2460// 默认占用2460字节, 1m等于1024k, 1k等于1024字节
      const errorSize = (parseFloat(size.value) / 2) * 100 * 1024// 误差
      const repeatTimes = designSize - defaultSize - errorSize;
      const doc = new jsPDF();
      doc.text("1".repeat(repeatTimes), 1010); // 1个数字为1字节
      doc.save(`约为${parseFloat(size.value)}m大小的pdf.pdf`);
    }
  </script>
</html>

解析:

核心思想就是计算需要代码生成的字节数,首先计算出需要的字节数parseFloat(size.value || 0) * 1024 * 1024,然后文件有一个默认占用字节数为2460和一个误差占用的字节数(parseFloat(size.value) / 2) * 100 * 1024,既需要代码生成的字节数=设计字节数-默认占用字节数-误差占用字节数, 最后因为每个1占用1个字节,所以用"1".repeat(repeatTimes)来生成需要的字节数。


PS: 受限于性能不要生成过大的pdf,生成的越大,卡顿的时间越长。至于最大能生成多大的,我也没试过,你可以试试。。。