我在 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 等...)。
如何在从 html 模板生成 PDF 的过程中添加自动页面编号?
这是一个解决方法!我尝试了你的
code
并遇到了问题,我研究了CSS - Footer Page Counter
,但似乎不起作用。
我还修改了
for loop
你的代码,添加了一些每页限制的变量以及DriveApp
pdf的保存位置。我还包括 pdf 合并使用 Google Apps 脚本在 Google Drive 中合并 PDF 文件。
示例输出:
代码.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>
参考资料: