本文主要是介绍jszip和pizzip中文乱码的解决方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
jszip中文乱码的解决方案
jszip官方文档地址:https://stuk.github.io/jszip/
1、问题分析
在JavaScript中需要用到对Zip压缩包进行操作时,我们往往会使用jszip
对压缩包进行编辑。
但是,当我们使用jszip
来读取包含中文名的文件时,文件名会出现乱码的情况。
下面的示例中我们使用jszip3.0
版本来进行读取testZip.zip
压缩包,压缩包中有三个中文的docx文件。
import JSZip from 'jszip'
import JSZipUtils from 'jszip-utils'export function useJSZip() {JSZipUtils.getBinaryContent('../../public/testZip.zip', function (err, data) {if (err) {throw err}JSZip.loadAsync(data).then(function (zip) {console.log(zip.files)/* Ђ• DOCX ΄••1.docxЂ• DOCX ΄••2.docxЂ• DOCX ΄••3.docx*/})})
}
代码中我们看到,本应该为新建 DOCX 文档1.docx
的文件名变为了乱码,这种情况下使用file-saver
进行保存时会出现问题。
通过查看jszip
的官方文档,我们可以看到jszip在读取文件名时对文件名默认使用UTF-8
的文件名解码。
一般中文压缩文件中的文件名都以gbk
形式进行编码,而jszip
在读取压缩包时,使用UTF-8
解码gbk
编码的文件名,这时就导致我们的文件名出现了乱码。
2、解决思路
通过上面的问题分析我们可以有两个解决思路。
1、第一个思路可以从jszip
的编码上进行解决,参考官方文档,如果我们使用的是jszip3.0
及以上的版本我们可以在loadAsync
方法的options
参数中自定义解码方法,这样jszip
在读取文件名解码时会以回调函数的形式执行并接受我们自定义的解码器所传入的文件名。
当然如果我们是想配合docxtemplater进行模板文档功能的实现时,jszip3.0并不能满足需求,因为docxtemplater仅仅支持到jszip2.0的版本和docxtemplater基于jszip2.0封装的pizzip。在jszip2.0中我们需要使用load方法来读取文件,并在里面自定义解码器。pizzip是官方基于jszip2.0进行封装的更适合docxtemplater算法的一个包,解决方法和使用方法与jszip2.0相同。
2、第二个思路是在压缩包文件本身进行解决,将压缩包的中文编码改为utf-8即可。
3、解决方法
1、对于自定义编码,我们可以使用第三方解码器iconv-lite
来实现gbk
的解码。
# 安装iconv-lite
npm i iconv-lite --save
# 在浏览器中运行时可能会报错缺少buffer包,如果出错使用下面代码安装
npm i buffer -D
jszip3.0解决方法
import JSZip from 'jszip'
import JSZipUtils from 'jszip-utils'
import iconv from 'iconv-lite'export function useJSZip() {JSZipUtils.getBinaryContent('../../public/testZip.zip', function (err, data) {if (err) {throw err}// 指定options编码器JSZip.loadAsync(data, {decodeFileName: function (bytes) {// 使用iconv-lite解码return iconv.decode(bytes, 'gbk')},}).then(function (zip) {console.log(zip.files)/* 新建 DOCX 文档1.docx新建 DOCX 文档2.docx新建 DOCX 文档3.docx*/})})
}
jszip2.0解决方法
import JSZip from 'jszip'
import JSZipUtils from 'jszip-utils'
import iconv from 'iconv-lite'export function renderZip() {JSZipUtils.getBinaryContent('../../public/testZip.zip',function (err, data) {if (err) {throw err // or handle err}const zip = new JSZip()zip.load(data, {decodeFileName: function (bytes) {// 使用iconv-lite库来解码gbkreturn iconv.decode(bytes, 'gbk')},})console.log(zip.files)/* 新建 DOCX 文档1.docx新建 DOCX 文档2.docx新建 DOCX 文档3.docx*/})
}
pizzip解决方法
import PizZip from 'pizzip'
import PizZipUtils from 'pizzip/utils/index.js'
import iconv from 'iconv-lite'export function renderZip() {PizZipUtils.getBinaryContent('../../public/testZip.zip',function (err, data) {if (err) {throw err // or handle err}const zip = new PizZip()zip.load(data, {decodeFileName: function (bytes) {// 使用iconv-lite库来解码gbkreturn iconv.decode(bytes, 'gbk')},})console.log(zip.files)/* 新建 DOCX 文档1.docx新建 DOCX 文档2.docx新建 DOCX 文档3.docx*/})
}
注意
- 配合
docxtempater
时推荐采用官方封装的pizzip
进行,可以使用jszip2.0
,但不能使用jszip3.0
及以上版本,因为高版本jszip
并没有被docxtemplater
适配支持。 - 使用
jszip2.0
和pizzip
时调用函数的方法基本一致,但是导入的方法不一致,jszip
在浏览器端读取本地文件时需要单独安装jszip-utils
包进行二进制数据的读取。而pizzip
将读取二进制文件的方法集成到包中,只需要导入pizzip
中的pizzip/utils/index.js
即可。
这篇关于jszip和pizzip中文乱码的解决方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!