情景
当前在做一个简历模板,有使用到网页打印转为 PDF 文件的功能。PDF 是转成功了,但是页码功能却很麻烦,以下是几种可以生成页面的方式。
1. 页面打印勾选
最简单的就是在打印时勾选页眉和页脚了。
但是这种方式会在页脚左侧显示当前网址,页眉显示生成时间和标题,一般简历 pdf 都不会带上这些东西的,带上这些别人可能会以为你不够专业。
2. 使用 css 中的 @page
@page 会在打印时生效,它的子选择器可以是@top-right
@bottom-right
等,配合 content 属性以及自增属性可以做到打印时生成页码,也就是它可以在 pdf 内容四周的白边上带上页码。
@page {
// 在页面右下角生成页码
@bottom-right {
content: counter(page) " of " counter(pages);
}
}
这东西看上去好像挺好的,但是有个天大的缺陷就是该功能只是昙花一现,目前已没有任何浏览器为它实现该功能。
3. 使用 pdf-lib
使用 pdf-lib可以读取一个已有的 PDF 文件,然后像添加水印一样为 PDF 文件的每个页面添加一个页码。
import { degrees, PDFDocument, rgb, StandardFonts } from 'pdf-lib';
async function modifyPdf() {
const url = 'https://pdf-lib.js.org/assets/with_update_sections.pdf'
const existingPdfBytes = await fetch(url).then(res => res.arrayBuffer())
const pdfDoc = await PDFDocument.load(existingPdfBytes)
const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica)
const pages = pdfDoc.getPages()
const firstPage = pages[0]
const { width, height } = firstPage.getSize()
firstPage.drawText('This text was added with JavaScript!', {
x: 5,
y: height / 2 + 300,
size: 50,
font: helveticaFont,
color: rgb(0.95, 0.1, 0.1),
rotate: degrees(-45),
})
const pdfBytes = await pdfDoc.save()
}
该方式优点是可在任意 js 环境中使用。
缺点则是需要用浏览器把 PDF 生成出来,然后再次为 PDF 文件生成页码,需要操作两步,除非用代码生成 PDF 才能简化为一步操作。
4. 代码插入
该方式需要固定住打印尺寸,然后计算出每个页面底部位置,然后插入页码,具体见 https://stackoverflow.com/a/64884005/23944718
<html>
<head>
<style type="text/css">
@page {
size: A4;
margin: 0;
}
body {
margin: 0;
}
</style>
</head>
<body>
<script type="text/javascript">
window.onload = addPageNumbers;
function addPageNumbers() {
var totalPages = Math.ceil(document.body.scrollHeight / 1123); //842px A4 pageheight for 72dpi, 1123px A4 pageheight for 96dpi,
for (var i = 1; i <= totalPages; i++) {
var pageNumberDiv = document.createElement("div");
var pageNumber = document.createTextNode("Page " + i + " of " + totalPages);
pageNumberDiv.style.position = "absolute";
pageNumberDiv.style.marginTop = "calc((" + i + " * (297mm - 0.5px)) - 40px)"; //297mm A4 pageheight; 0,5px unknown needed necessary correction value; additional wanted 40px margin from bottom(own element height included)
pageNumberDiv.style.height = "16px";
pageNumberDiv.appendChild(pageNumber);
document.body.insertBefore(pageNumberDiv, document.getElementById("content"));
pageNumberDiv.style.left = "calc(100% - (" + pageNumberDiv.offsetWidth + "px + 20px))";
}
}
</script>
<div id="content">
Lorem ipsum....
</div>
</body>
</html>
该方式也是可以的,固定尺寸其实问题也不大,毕竟简历打印都是 A4 大小的。
5. Paged.js
该方式见于 https://stackoverflow.com/a/66688870/23944718 ,我也没试过,但是有人说可以,有人说有问题,先搁这吧。
最后
以上各方法各有优缺点,我目前用的是用网页生成 PDF 文件,用pdf-lib
为 PDF
文件生成页码,其实最优选还是用库生成 PDF文件,这样就能随心所欲想要什么样式就什么样式,但是因为我的是 html 的,用库生成的话挺麻烦的要搞两套样式,所以先就这样了。
评论