我使用jsPDF(https://parall.ax/products/jspdf,https://github.com/MrRio/jsPDF),以产生一个Web应用程序的动态PDF文件。
它运作良好,但我想弄清楚是否有可能在生成的PDF中使用Google网络字体。
我已经找到了许多与此问题相关的链接(包括关于SO的其他问题),但是大多数链接都已过时,并且似乎没有确定的链接,因此我希望有人阐明这是否/如何进行。
到目前为止,这是我尝试过的尝试,但没有成功:
首先,加载字体,并将其缓存为base64编码的字符串:
var arimoBase64;
var request = new XMLHttpRequest()
request.open('GET', './fonts/Arimo-Regular.ttf');
request.responseType = 'blob';
request.onload = function() {
var reader = new FileReader();
reader.onloadend = function() {
arimoBase64 = this.result.split(',')[1];
}
reader.readAsDataURL(this.response);
};
request.send()
Run Code Online (Sandbox Code Playgroud)
接下来,创建pdf doc
:
doc = new jsPDF({
orientation: "landscape",
unit: "pt",
format: "letter"
});
doc.addFileToVFS("Arimo-Regular.ttf", arimoBase64);
doc.addFont("Arimo-Regular.ttf", "Arimo Regular", "normal");
doc.setFont("Arimo Regular", "normal");
doc.text("Hello, World!", 100, 100);
doc.save("customFontTest");
Run Code Online (Sandbox Code Playgroud)
保存PDF后-如果在浏览器中查看它-我可以看到自定义字体。但是,如果我使用Adobe Reader或Mac Preview应用查看它,则字体不可见。
我认为这是因为字体是使用浏览器的字体缓存在浏览器中呈现的,但是该字体实际上并未嵌入PDF中,这就是为什么在Adobe Reader中看不到该字体的原因。
所以-有没有办法完成我想做的事情?
好的-我终于弄清楚了,并使其正常工作。万一这对其他人有用-这是我正在使用的解决方案...
首先-您需要两个库:
下一步-第二个库要求您在名为的文件中为其提供至少一种自定义字体default_vfs.js
。
该文件应如下所示:
(function (jsPDFAPI) {
"use strict";
jsPDFAPI.addFileToVFS("[Your font's name]","[Base64-encoded string of your font]");
})(jsPDF.API);
Run Code Online (Sandbox Code Playgroud)
我正在使用两种自定义字体-Arimo-Regular.ttf和Arimo-Bold.ttf-都来自Google字体。因此,我的default_vfs.js
文件如下所示:
(function (jsPDFAPI) {
"use strict";
jsPDFAPI.addFileToVFS("Arimo-Regular.ttf","[Base64-encoded string of your font]");
jsPDFAPI.addFileToVFS("Arimo-Bold.ttf","[Base64-encoded string of your font]");
})(jsPDF.API);
Run Code Online (Sandbox Code Playgroud)
有很多方法可以获取字体的Base64编码的字符串,但是我使用了以下方法:https : //www.giftofspeed.com/base64-encoder/。
它允许您上载.ttf字体文件,并提供可以粘贴到的Base64字符串default_vfs.js
。
您可以在这里用我的字体查看实际文件的外观:https : //cdn.rawgit.com/stuehler/jsPDF-CustomFonts-support/master/dist/default_vfs.js
因此,一旦将字体存储在该文件中,您的HTML应如下所示:
<script src="js/jspdf.min.js"></script>
<script src="js/jspdf.customfonts.min.js"></script>
<script src="js/default_vfs.js"></script>
Run Code Online (Sandbox Code Playgroud)
最后,您的JavaScript代码如下所示:
const doc = new jsPDF({
unit: 'pt'
});
doc.addFont("Arimo-Regular.ttf", "Arimo", "normal");
doc.addFont("Arimo-Bold.ttf", "Arimo", "bold");
doc.setFont("Arimo");
doc.setFontType("normal");
doc.setFontSize(28);
doc.text("Hello, World!", 100, 100);
doc.setFontType("bold");
doc.text("Hello, BOLD World!", 100, 150);
doc.save("customFonts.pdf");
Run Code Online (Sandbox Code Playgroud)
这对于大多数人来说可能很明显,但是在该addFont()
方法中,三个参数是:
addFileToVFS()
在default_vfs.js
文件中的函数中使用的字体名称setFont()
在JavaScript函数中使用的字体名称setFontType()
在JavaScript函数中使用的字体样式您可以在这里看到此工作:https : //codepen.io/stuehler/pen/pZMdKo
希望这对您和我都一样有效。
我最近遇到了同样的问题,但看起来 jsPDF-CustomFonts-support 存储库已被纳入 MrRio 的 jsPDF 存储库,因此您不再需要它来使其正常工作。
我碰巧在 React 应用程序中使用它并执行以下操作:
npm install jspdf
fonts/index.js
(注意:您可以将 Google 字体下载为 .ttf 并使用mattstuehler 的答案中的工具将其转换为 Base64 编码的字符串)export const PlexFont = "[BASE64 Encoded String here]";
Run Code Online (Sandbox Code Playgroud)
import jsPDF from 'jspdf';
import { PlexFont } from '../fonts';
// Other Reacty things...
exportPDF = () => {
const doc = new jsPDF();
doc.addFileToVFS('IBMPlexSans-Bold.ttf', PlexBold);
doc.addFont('IBMPlexSans-Bold.ttf', 'PlexBold', 'normal')
doc.setFont('PlexBold');
doc.text("Some Text with Google Fonts", 0, 0);
// Save PDF...
}
// ...
Run Code Online (Sandbox Code Playgroud)