当表格跨多页时如何添加自动页面编号

问题描述 投票:0回答:1

我在 Google App Scripts Web 应用程序中有一个 HTML,其中包含一个可能跨越多个页面的表格,并且我想在每个页面的右下角添加页面编号,例如“第 3/4 页”。页码应包括当前页和总页数。

这是重现该问题的简单测试代码。

脚本:

function doPost(e) {
  try {
    const template = HtmlService.createTemplateFromFile('test');
    const tableData = [];
    for (i = 0; i < 100; i ++) { // 100 could be any number
      tableData.push({ code: 1, product: 'shampoo'});
    }
    template.tableRows = tableData;
    const htmlOutput = template.evaluate().getContent();
    const pdfBlob = Utilities.newBlob(htmlOutput, 'text/html').getAs('application/pdf');
    pdfBlob.setName('some.pdf');
    const pdfBytes = pdfBlob.getBytes();
    const pdfBase64 = Utilities.base64Encode(pdfBytes);
    console.log(pdfBase64)
    return ContentService.createTextOutput(JSON.stringify({ pdf: pdfBase64 })).setMimeType(ContentService.MimeType.JSON);
  } catch (error) {
    console.error(error)
    return ContentService.createTextOutput().setMimeType(ContentService.MimeType.JSON);;
  }
}

测试.html:

<!DOCTYPE html>
<html>

<head>
  <base target="_top">
</head>
<style>
  @page {
    size: A4;
    margin: 0;
    counter-increment: page;
  }

  .page-footer {
    position: fixed;
    bottom: 0;
    right: 0;
    margin: 10px;
    font-size: 10px;
  }

  .page-footer::after {
    content: counter(page);
  }
</style>
<body>
  <table>
    <thead>
      <tr>
        <th>Code</th>
        <th>Product</th>
      </tr>
    </thead>
    <tbody>
      <? tableRows.forEach(function (item) { ?>
      <tr>
        <td>
          <?= item.code ?>
        </td>
        <td>
          <?= item.product ?>
        </td>
      </tr>
      <? }); ?>
    </tbody>
    <div class="page-footer"></div>
</body>

</html>

此代码在每页末尾的右下角生成一个“0”,而不是预期的页面编号(即 1、2、3 等...)。

enter image description here

如何在从 html 模板生成 PDF 的过程中添加自动页面编号?

javascript google-apps-script pdf web-applications pagination
1个回答
0
投票

将 HTML 转换为带有页码的 PDF

这是一个解决方法!我尝试了你的

code
并遇到了问题,我研究了
CSS - Footer Page Counter
,但似乎不起作用。

我还修改了

for loop
你的代码,添加了一些每页限制的变量以及
DriveApp
pdf的保存位置。我还包括 pdf 合并使用 Google Apps 脚本在 Google Drive 中合并 PDF 文件


示例输出:

Sample 1

sample 2

Sample 3


代码.gs

const folderId = "--Folder Id --";

async function combinePDFs(childFolderId) {
  const parentFolder = DriveApp.getFolderById(folderId);
  const childFolder = DriveApp.getFolderById(childFolderId);
  const files = childFolder.getFiles();

  // Merge PDFs.
  const cdnjs = "https://cdn.jsdelivr.net/npm/pdf-lib/dist/pdf-lib.min.js";
  eval(UrlFetchApp.fetch(cdnjs).getContentText()); // Load pdf-lib
  const setTimeout = function (f, t) {
    Utilities.sleep(t);
    return f();
  }
  const pdfDoc = await PDFLib.PDFDocument.create();
  while (files.hasNext()) {
    const file = files.next();
    Logger.log(file.getName() + ' ' + file.getMimeType());
    if (file.getMimeType() === 'application/pdf') {
      const pdfData = await PDFLib.PDFDocument.load(new Uint8Array(file.getBlob().getBytes()));
      const pages = await pdfDoc.copyPages(pdfData, [...Array(pdfData.getPageCount())].map((_, i) => i).sort());
      pages.forEach(page => pdfDoc.addPage(page));
    }
  }
  const bytes = await pdfDoc.save();

  // Create a PDF file.
  parentFolder.createFile(Utilities.newBlob([...new Int8Array(bytes)], MimeType.PDF, "Merged.pdf"));
  childFolder.setTrashed(true);
}

function doPost() {
  try {
    const parentFolder = DriveApp.getFolderById(folderId);
    const createChildFolder = parentFolder.createFolder("TempFiles").getId();
    const template = HtmlService.createTemplateFromFile('test');
    let tableData = [];
    const limit = 20; // Limit per page.
    const totalData = 100; // Total Data.
    const equation = totalData - Math.round((limit * (totalData / limit)));
    let page = Math.round(totalData / limit) + 1;
    for (i = 1; i < totalData + 1; i++) { 
      tableData.push({ code: 1, product: 'shampoo' });
      if (i % limit === 0) {
        createPdf()
      } else if (i > (totalData - equation) && tableData.length === equation) {
        createPdf();
      }
    }

    function createPdf() {
      template.tableRows = tableData;
      template.pages = page -= 1;
      const htmlOutput = template.evaluate().getContent();
      const pdfBlob = Utilities.newBlob(htmlOutput, 'text/html').getAs('application/pdf');
      pdfBlob.setName(`some${page}.pdf`);
      uploadFile(pdfBlob, createChildFolder);
      tableData = []
      console.log(page);
    }
    combinePDFs(createChildFolder)


  } catch (error) {
    console.error(error)
    return ContentService.createTextOutput().setMimeType(ContentService.MimeType.JSON);;
  }
}

function uploadFile(pdf, childFolder) {
  const folder = DriveApp.getFolderById(childFolder);
  const file = folder.createFile(pdf);
  file.setDescription("Temp Pdf");
  console.log("File Uploaded!");
}

测试.html

<!DOCTYPE html>
<html>

<head>
  <base target="_top">
</head>
<style>
  @page {
    size: A4;
    margin: 0;
  }

  .page-footer {
    position: fixed;
    bottom: 0;
    right: 0;
    margin: 10px;
    font-size: 10px;
  }
</style>

<body>
  <table>
    <thead>
      <tr>
        <th>Code</th>
        <th>Product</th>
      </tr>
    </thead>
    <tbody>
      <? tableRows.forEach(function (item) { ?>
      <tr>
        <td>
          <?= item.code ?>
        </td>
        <td>
          <?= item.product ?>
        </td>
      </tr>
      <? }); ?>
    </tbody>
    <div class="page-footer">
      <?= pages ?>
    </div>
</body>

</html>

参考资料:

© www.soinside.com 2019 - 2024. All rights reserved.