我正在尝试向 jsPDF 添加自定义字体。我将文件转换为 base64 并执行了以下操作:
doc.addFileToVFS("font/rajdhani-regular-webfont.woff", base64enc);
其中base64enc是base 64编码的字符串
然后我添加字体如下:
doc.addFont('font/rajdhani-regular-webfont.woff', 'rajdhani', 'normal');
doc.setFont('rajdhani');
但是,我不断收到以下错误
[Error] jsPDF PubSub Error – "No unicode cmap for font" – Error: No unicode cmap for font — jspdf.min.js:9068
Error: No unicode cmap for font — jspdf.min.js:9068registerTTF — jspdf.min.js:9068i — jspdf.min.js:9027:86open — jspdf.min.js:9032(anonymous function) — jspdf.min.js:6031publish — jspdf.min.js:308yt — jspdf.min.js:729:166addFont — jspdf.min.js:1286callme — freport.php:500onclick — freport.php:100
publish (jspdf.min.js:29:5989)
yt (jspdf.min.js:29:18435)
addFont (jspdf.min.js:29:33701)
callme (freport.php:500)
onclick (freport.php:100)
我不知道为什么会这样。
我也一直在挣扎,但我终于找到了方法!
正如这里提到的,有一个由jsPDF贡献者制作的字体转换器,您可以在这里找到。
首先在此处上传您的字体,然后输入您的字体名称。它将生成 JS 文件,然后您需要将其包含在您的项目中。如果您愿意,这可以是您的 js 文件夹。
一旦它进入您的文件夹,请将此脚本标签添加到您的index.html(或您需要jsPDF的任何html文件)。
<script src="./fontName.js"></script>
现在您已经使用该文件将字体自动添加到 jsPDF Api 中,您可以继续操作并从代码中删除以下两行。
doc.addFileToVFS("font/rajdhani-regular-webfont.woff", base64enc);
doc.addFont('font/rajdhani-regular-webfont.woff', 'rajdhani', 'normal');
完成此操作后,只需检查从转换器下载的文件,您应该在最底部看到您的字体名称位于以下代码的第二个参数。
this.addFont('fontFile.woff', 'THIS IS FONT NAME' , '.......');
复制该名称。对于这个例子,我们可以说它是“rajdhani”。因此,您只需将其放在在 jsPDF (doc) 实例上创建的任何文本之前即可。
doc.setFont('rajdhani');
您可以简单地用下面的方法进行测试
/*
"p" for portrait page orientation
"pt" for points. default is mm
"a4" is page size
*/
var doc = new jsPDF("p","pt","a4");
doc.setFont('rajdhani');
doc.text('This is a test', 20,20);
doc.save('filename.pdf');
现在您应该会看到一个 pdf,其上边距为 20px,左 20px,并用您的字体样式写着“这是一个测试”。
希望这有帮助:)
对于 ES6 模块用户来说,步骤也非常相似。
如果您像我一样在这里寻找 Ionic 4 Angular TypeScript 的解决方案,下面是对我有用的解决方案!
首先您需要通过 npm 安装软件包,如下所示。
npm install jspdf@latest --save
之后,正如我之前的回复中提到的,有一个由 jsPDF Contributers 制作的字体转换器,您可以在here找到它。使用它来上传您的字体文件并将其包含在您的项目中易于引用的 TS 文件中的某个位置,因此它可以与 ts 文件位于同一文件夹中。
-fontname-style.js // <<--- Here (This is the file you downloaded from converter)
-custom.page.module.ts
-custom.page.html
-custom.page.scss
-custom.page.spec.ts
-custom.page.ts
现在在您的 custom.page.ts 中导入以下内容;
import * as jsPDF from 'jspdf';
import './fontname-style.js';
//OPTIONAL (Only import if you want to use autotable)
import 'jspdf-autotable';
import { autoTable as AutoTable } from 'jspdf-autotable';
完成此操作后,只需检查从转换器下载的文件,您应该在最底部看到下面代码的第二个参数上的字体名称。
this.addFont('fontFile.ttf', 'fontName', '.......');
现在您可以在 custom.page.ts 中创建这样的函数;
//custom.component.ts or custom.page.ts etc.
exportPDF(){
var doc = new jsPDF("p","pt","a4"); // You can set your own paramaters
doc.setFont('fontName');
doc.text('This is a test', 20,20); // You can set your own margins
return doc.save('filename.pdf');
}
现在您应该会看到一个 pdf,左上边距为 20px,上边距为 20px,并用您的字体样式写着“这是一个测试”:)
可选插件 - AutoTable for jsPDF
如果您想使用 jsPDF 的 autotable 插件,请从 npm 安装以下软件包。
npm install jspdf-autotable@latest --save
安装后,将这两个导入添加到您的custom.page.ts。
import 'jspdf-autotable';
import { autoTable as AutoTable } from 'jspdf-autotable';
如果您愿意,您可以创建列和标题数据
在我们之前创建的exportPDF()函数中添加这些行;
//custom.component.ts or custom.page.ts etc.
exportPDF(){
var doc = new jsPDF("p","pt","a4");
doc.setFont('fontName');
doc.text('This is a test', 20,20); // <-- Remove this line
((doc as any).autoTable as AutoTable)({
head: [['Name', 'Email', 'Country']], // <-- Table headers
body: [ // <-- Table body
['David', '[email protected]', 'Sweden'],
['Castille', '[email protected]', 'Norway'],
// ...
],
styles: { font: "fontName" } /* <-- This is for the font to work in your
table */
});
return doc.save('filename.pdf');
}
现在您应该获得一个 pdf 文件,其中包含使用您的字体的表格:)
我希望这对某人有帮助。
我遇到了同样的问题,并按照@TuncGerdan 解释的步骤进行操作。我的错误已清除,但我在控制台中收到以下警告。
jspdf.min.js:29 Unable to look up font label for font 'font name', 'normal'. Refer to getFontList() for available fonts.
当我使用 doc.getFontList() 获取字体列表时,我可以看到列表中包含的自定义字体。
有人可以帮忙吗。
当我尝试以二进制形式添加新字体而没有像
docs中提到的转换器时,我也得到了
Error: No unicode cmap for font
。我认为他们的例子中的关键是:
const myFont = ... // load the *.ttf font file as binary string
对我来说,不清楚
binary string
的含义。然而,查看他们的转换器可以清楚地看出 binary string
应该是一个 base64 编码的字符串。
所以对我来说,从远程获取字体并添加它可以使用以下方法:
/**
* load a font from remote and add it to jsPDF doc
* @param path the path of the font, e.g. '/app/fonts/My-Font.ttf'
* @param doc the jsPDF doc instance to install the font to
* @return {Promise<void>}
*/
async function loadFont(path, doc) {
let response = await fetch(path).catch((e) => console.error(e));
if (!response) {
return;
}
let fontName = path.substring(path.lastIndexOf("/") + 1);
console.log("using font", fontName);
let contentBuffer = await response.arrayBuffer();
let contentString = util.arrayBufferToBase64(contentBuffer)
if (contentString) {
doc.addFileToVFS(fontName, contentString);
doc.addFont(fontName, fontName, "normal");
doc.setFont(fontName);
}
}
对于
util.arrayBufferToBase64
我正在使用这个Stackoverflow答案中的函数。
我遇到了一个重要问题!不支持 WOFF 和 OTT(坚持使用 ttf)。我在这方面浪费了太多时间,这个功能应该是标准的。事实上,他们有一个狡猾的转换器网站而不是内置功能,这一事实令人难以置信(也没有提到文件类型限制,在他们的应用程序上进行了简单的扩展检查),类似于@klues,但使用文件阅读器来简化,这里是我的角度功能
this.loadFont('VIC-med', 'assets/Fonts/VIC-Medium.ttf');
loadFont(fontName: string, filePath: string, weight: 'normal'| 'bold' | 'italic'| 'bolditalic' = 'normal') {
this.http.get(filePath, { responseType: 'blob' })
.subscribe({
next: (blob: Blob) => {
const fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
const reader = new FileReader();
reader.onloadend = () => {
const file64 = (reader.result as string).split(',')[1];
this.pdf.addFileToVFS(fileName, atob(file64));
this.pdf.addFont(fileName, fontName, weight);
};
reader.readAsDataURL(blob);
},
error: (error) => {
console.error('Error loading font:', error);
}
});
}
对于 ES 来说也是如此
loadFont(fontName: string, filePath: string, weight: 'normal'| 'bold' | 'italic'| 'bolditalic' = 'normal') {
fetch(filePath)
.then(response => response.blob())
.then(blob => {
const fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
const reader = new FileReader();
reader.onloadend = () => {
const file64 = (reader.result as string).split(',')[1];
this.pdf.addFileToVFS(fileName, atob(file64));
this.pdf.addFont(fileName, fontName, weight);
};
reader.readAsDataURL(blob);
})
.catch(error => {
console.error('Error loading font:', error);
});
}