首页 > 其他分享 >jsPDF 文字、图片生成PDF(解决中文乱码)

jsPDF 文字、图片生成PDF(解决中文乱码)

时间:2024-03-08 11:56:39浏览次数:16  
标签:jsPDF doc 乱码 字体 https arg PDF font addFont

JSPDF官网在线演示地址(不支持中文)

思源黑体字体库下载地址:https://gitee.com/ABCpril/SourceHansTtf    https://github.com/adobe-fonts/source-han-sans/blob/release/README.md (后面一个是完整的包、比较大,一般用前面一种)

JSPDF支持中文(思源黑体)采坑之旅,JSPDF中文字体乱码解决方案

众所周知,JSPDF是一个开源的,易用的,但是对中文支持非常差的PDF库。

下面,我教大家,如何在pdf中使用思源黑体。思源黑体是开源字体。思源黑体具有很广泛使用性,实用性,也是规避字体版权风险的重要选择!请严格按照我说的做!

1、准备思源黑体的ttf文件,不要用otf文件,如下

https://github.com/be5invis/source-han-sans-ttf/releases

我们挑其中的SourceHanSans-Bold.ttfSourceHanSans-Normal.ttf来使用,代表一粗一细。

2、把下载的字体命名统统改为小写,如下

 为什么改为小写,见 issues2465 ,命名为大写的统统失效~

 

解决中文乱码问题
1、去这里下载一个ttf字体文件,或者自己从别处下载(字体文件越小越好)
2、去这里将项目clone下来,打开 fontconverter/fontconverter.html,操作如下图

或者在这个网站进行转换https://rawgit.com/MrRio/jsPDF/master/fontconverter/fontconverter.html

注意,这个网站就算挂了,我们也可以在jspdf的源码里找到转换器 https://github.com/MrRio/jsPDF/blob/master/fontconverter/fontconverter.html

 转换成后把字体文件生成对应的js文件

 3、于是,我们得到这2个文件

 PS:字体是bold字体,网站的fontStyle你就选bold,normal也是这样!

用记事本(win)打开这2个文件,不要用编辑器,会异常卡,除非你内存高,mac爱什么打开什么打开,双击选中那串长的,ctrl+c。

 

你的项目新建font.js,内容如下

export function addfont(pdf) {

       var font = 'AADSSDDT12......'     // ←就是很长那串 
       pdf.addFileToVFS('bolds', font)  return true;
}

使用方法:(我的项目是ant-design pro 4.0)

import { addfont } from '@/font/font'
//前面只是添加了字体,还要注册字体,addfont第3个参数一定是normal,即使你add的字体是bold的,也要设置为normal
addfont(doc)
doc.addFont('bolds', 'b', 'normal')

//使用字体时,使用这句即可
doc.setFont('b');

坑:

1、autoTable需要使用默认字体,是一种叫做NotoSansCJKtc-Regular.ttf的字体,否则乱码,或者你改源码,使之兼容

 

 doc.addFont('NotoSansCJKtc-Regular.ttf', 'NotoSansCJKtc', 'normal');
 doc.setFont('NotoSansCJKtc');

2、因为字体文件太大,导致JS运行时内存溢出 JavaScript heap out of memory

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory

 

资料:https://stackoverflow.com/questions/38558989/node-js-heap-out-of-memory

解决办法:https://lwjandmy.github.io/myblog/articles/+.+category+.+%E7%BC%96%E7%A8%8BJavaScript+.+title+.+node%20%E5%87%BA%E7%8E%B0heap%20out%20of%20memory%E9%97%AE%E9%A2%98+.+createtime+.+20181228%E4%B8%80190612+.+lastmodifiedtime+.+20181228%E4%B8%80190612+.+.html

 

 由于我用了umi,因此改umi.cmd,如下

@IF EXIST "%~dp0\node.exe" (
  "%~dp0\node.exe"  "%~dp0\..\umi\bin\umi.js" %*
) ELSE (
  @SETLOCAL
  @SET PATHEXT=%PATHEXT:;.JS;=;%
  node --max-old-space-size=4096  "%~dp0\..\umi\bin\umi.js" %*
)

若你是用webpack,改webpack.cmd

3、最后不得不说句,我把字体放在前端项目,是因为我的项目要打包为electron的,若你的项目是发布到线上,最好做cdn或者考虑使用默认一种字体~!

由于字体文件实在太大,执行打包时必定触发V8的内存限制,我使用umi打包时,8G内存直接爆了,--max-old-space-size=7000也不起作用,换成mac的16G内存一样爆了,问题在哪?思维错了!我们不能苛求webpack/umi能够具有打包系统级文件的能力:如大型音视频,字体包,压缩文件,msi等,此时只有使用系统的文件管理能力来加持,因此,ele的原生能力就要发挥作用。

用到线程通信和node的文件读取能力即可

https://electronjs.org/docs/api/ipc-main

// 在主进程中.
const { ipcMain } = require('electron')
ipcMain.on('asynchronous-message', (event, arg) => {
  console.log(arg) // prints "ping"
  event.reply('asynchronous-reply', 'pong')
})

ipcMain.on('synchronous-message', (event, arg) => {
  console.log(arg) // prints "ping"
  event.returnValue = 'pong'
})
//在渲染器进程 (网页) 中。
const { ipcRenderer } = require('electron')
console.log(ipcRenderer.sendSync('synchronous-message', 'ping')) // prints "pong"

ipcRenderer.on('asynchronous-reply', (event, arg) => {
  console.log(arg) // prints "pong"
})
ipcRenderer.send('asynchronous-message', 'ping')

所谓渲染器进程就是你的前端项目,下面说一下的处理方式

1 准备字体文件

2.由于不是项目主要部分,而是支持性部分,因此我就用了一个回调地狱   /滑稽

var fs = require("fs");
ipcMain.on('asynchronous-message', (event, arg) => {
  console.log('main', arg) // 请求的消息

  // 使用通信方式输送字体给前端
  let filePath = path.join(__dirname, ".", "font/font.js");
  let filePath2 = path.join(__dirname, ".", "font/font2.js");
  let filePath3 = path.join(__dirname, ".", "font/font3.js");
  console.log(filePath, "filePath")

  fs.readFile(filePath, { encoding: "utf-8" }, function (err, fr) {
    //readFile回调函数
    // if (err) {
    //   console.log(err);
    // } 

    fs.readFile(filePath2, { encoding: "utf-8" }, function (err, fr2) {
      //readFile回调函数

      fs.readFile(filePath3, { encoding: "utf-8" }, function (err, fr3) {
        //readFile回调函数

        event.reply('asynchronous-reply', {
          addFont: fr,
          addFont2: fr2,
          addFont3: fr3,
        })
      })
    })
  })
})

前端调用

const { ipcRenderer } = require('electron') 

 ipcRenderer.send('asynchronous-message', 'ping')
 ipcRenderer.on('asynchronous-reply', (event, arg) => {
      // console.log('web', arg) // prints "pong"

      const {
        addFont,
        addFont2,
        addFont3
      } = arg

      this.setState({
        addFont,
        addFont2,
        addFont3
      })
})

使用字体

doc.addFileToVFS('bolds', this.state.addFont)
doc.addFileToVFS('normals', this.state.addFont2)

doc.addFont('bolds', 'b', 'normal')
doc.addFont('normals', 'n', 'normal')

...
doc.setFont('n');


...
doc.setFont('b');

上面解决方案参考来源:https://www.cnblogs.com/ww01/p/11496213.html

其他参考来源:https://www.jianshu.com/p/756141b50ad8   

https://blog.csdn.net/qq_43436008/article/details/134425543

http://easypeak.me/jsPDF-CustomFonts-support/#

 

标签:jsPDF,doc,乱码,字体,https,arg,PDF,font,addFont
From: https://www.cnblogs.com/andydao/p/18060680

相关文章

  • 【专题】2023年中国奢侈品市场数字化趋势洞察报告PDF合集分享(附原数据表)
    原文链接:https://tecdat.cn/?p=33672原文出处:拓端数据部落公众号2022年,中国的奢侈品消费市场一直处于不断变化和挑战之中,但随着2023年的到来,中国正在全面复苏,市场也充满了机遇和想象空间。自2019年以来,奢侈品品牌一直在中国尝试本地化和数字化策略,将中国的奢侈品消费者与国内市......
  • 【专题】大健康趋势洞察报告PDF合集分享(附原数据表)
    原文链接:https://tecdat.cn/?p=33947原文出处:拓端数据部落公众号在疫情的背景下,健康话题备受关注,民众对健康的意识不断提高,这促使了健康产业的蓬勃发展。阅读原文,获取专题报告合集全文,解锁文末242份大健康相关行业研究报告。首先,国家对中药材产业的扶持力度不断增强,推动了中药......
  • 如何将PDF文件无损压缩到更小?
    有时候我们为了提高文件传输速度,会适当压缩一下PDF文件大小,但很多朋友不知道怎么将PDF文件压缩的小一点,考虑到下载安装软件比较复杂还只能电脑使用,下面就给大家分享二个在线就能PDF压缩得方法,一起来了解下吧。方法一:ilovepdf中文版ilovepdf中文版是一款专业的在线PDF转换工具,网......
  • 值得收藏的几款免费pdf转成图片的在线工具
    如何将PDF转成图片?在数字化时代,PDF文件已成为我们日常生活和工作中不可或缺的一部分。有时我们也需要将PDF文件转换为图片格式,以便更方便地分享、编辑或打印。接下来为你推荐几款备受好评的PDF转图片在线工具,帮助你轻松转换各种格式文件。1.ilovepdf在线工具中文版ilovepdf中文......
  • 美能达423一体机打印pdf文件报错
    美能达423一体机打印pdf文件报错,出纸一张,左上角有小字显示PCL6err。打印一直很正常,同事打印了三页内有图片表格的pdf文件只出纸一张,左上角有小字显示PCL6err,开始的想法是不可能啊,再试,一样,重新打开文档,再试,一样,换一个电脑打印同一个pdf文档,试了一样,wps,acrobat,edge试了也一样,笨......
  • 《MySQL是怎样运行的:从根儿上理解 MySQL》PDF
    《MySQL是怎样运行的:从根儿上理解MySQL》采用诙谐幽默的表达方式,对MySQL的底层运行原理进行了介绍,内容涵盖了使用MySQL的同学在求职面试和工作中常见的一些核心概念。《MySQL是怎样运行的:从根儿上理解MySQL》总计22章,划分为4个部分。第1部分介绍了MySQL入门的一些知识,比如MySQ......
  • 【专题】2023年金融、保险、银行行业报告汇总PDF合集分享(附原数据表)
    原文链接:https://tecdat.cn/?p=35149原文出处:拓端数据部落公众号自中国提出双碳目标以来,可持续金融市场呈现出蓬勃发展的态势。这一发展趋势在多年来得到可持续金融战略咨询团队的支持和推动。同时,数字化转型的深入推进推动了新客户的增长,而中国的碳金融创新也成为市场关注的焦......
  • vue中PDF文件转图片方式
    1、在vue中安装依赖 pdfjs-dist  2、在需要引用的文件中添加import*aspdfjsfrom'pdfjs-dist'import*aspdfjsWorkerfrom'pdfjs-dist/build/pdf.worker.entry'pdfjs.GlobalWorkerOptions.workerSrc=pdfjsWorker3、编写需要转换的方法<divv-for="(i......
  • PDFBox-Android添加图片被遮挡
    使用pdfbox-android在已存在的pdf上面追加图片,需要先创建PDPageContentStream,在创建的时候需要注意设置模式为APPEND,并且将resetContext参数设置为truevalcs=PDPageContentStream(document,......
  • 【HMS Core】集成推送服务,打包后应用名乱码
    ​【问题描述】使用flutter进行移动端开发,导入了agconnect-services.json之后,成功集成了华为推送,但是应用打包如果应用名为中文,debug包生成的应用名会是乱码。​​ 【问题分析】1、经推测可能是agc插件与开发者引入的另外的sdk相冲突导致的,但即使去掉其他的sdk也会导致该问......