jszip和pizzip中文乱码的解决方案

2024-01-29 09:12

本文主要是介绍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.0pizzip时调用函数的方法基本一致,但是导入的方法不一致,jszip在浏览器端读取本地文件时需要单独安装jszip-utils包进行二进制数据的读取。而pizzip将读取二进制文件的方法集成到包中,只需要导入pizzip中的pizzip/utils/index.js即可。

这篇关于jszip和pizzip中文乱码的解决方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/656426

相关文章

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

Redis出现中文乱码的问题及解决

《Redis出现中文乱码的问题及解决》:本文主要介绍Redis出现中文乱码的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 问题的产生2China编程. 问题的解决redihttp://www.chinasem.cns数据进制问题的解决中文乱码问题解决总结

全面解析MySQL索引长度限制问题与解决方案

《全面解析MySQL索引长度限制问题与解决方案》MySQL对索引长度设限是为了保持高效的数据检索性能,这个限制不是MySQL的缺陷,而是数据库设计中的权衡结果,下面我们就来看看如何解决这一问题吧... 目录引言:为什么会有索引键长度问题?一、问题根源深度解析mysql索引长度限制原理实际场景示例二、五大解决

SpringSecurity显示用户账号已被锁定的原因及解决方案

《SpringSecurity显示用户账号已被锁定的原因及解决方案》SpringSecurity中用户账号被锁定问题源于UserDetails接口方法返回值错误,解决方案是修正isAccountNon... 目录SpringSecurity显示用户账号已被锁定的解决方案1.问题出现前的工作2.问题出现原因各

javax.net.ssl.SSLHandshakeException:异常原因及解决方案

《javax.net.ssl.SSLHandshakeException:异常原因及解决方案》javax.net.ssl.SSLHandshakeException是一个SSL握手异常,通常在建立SS... 目录报错原因在程序中绕过服务器的安全验证注意点最后多说一句报错原因一般出现这种问题是因为目标服务器

C++高效内存池实现减少动态分配开销的解决方案

《C++高效内存池实现减少动态分配开销的解决方案》C++动态内存分配存在系统调用开销、碎片化和锁竞争等性能问题,内存池通过预分配、分块管理和缓存复用解决这些问题,下面就来了解一下... 目录一、C++内存分配的性能挑战二、内存池技术的核心原理三、主流内存池实现:TCMalloc与Jemalloc1. TCM

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案(最新整理)

《MyBatisPlus中update_time字段自动填充失效的原因分析及解决方案(最新整理)》在使用MyBatisPlus时,通常我们会在数据库表中设置create_time和update... 目录前言一、问题现象二、原因分析三、总结:常见原因与解决方法对照表四、推荐写法前言在使用 MyBATis

Java死锁问题解决方案及示例详解

《Java死锁问题解决方案及示例详解》死锁是指两个或多个线程因争夺资源而相互等待,导致所有线程都无法继续执行的一种状态,本文给大家详细介绍了Java死锁问题解决方案详解及实践样例,需要的朋友可以参考下... 目录1、简述死锁的四个必要条件:2、死锁示例代码3、如何检测死锁?3.1 使用 jstack3.2

html 滚动条滚动过快会留下边框线的解决方案

《html滚动条滚动过快会留下边框线的解决方案》:本文主要介绍了html滚动条滚动过快会留下边框线的解决方案,解决方法很简单,详细内容请阅读本文,希望能对你有所帮助... 滚动条滚动过快时,会留下边框线但其实大部分时候是这样的,没有多出边框线的滚动条滚动过快时留下边框线的问题通常与滚动条样式和滚动行

Oracle修改端口号之后无法启动的解决方案

《Oracle修改端口号之后无法启动的解决方案》Oracle数据库更改端口后出现监听器无法启动的问题确实较为常见,但并非必然发生,这一问题通常源于​​配置错误或环境冲突​​,而非端口修改本身,以下是系... 目录一、问题根源分析​​​二、保姆级解决方案​​​​步骤1:修正监听器配置文件 (listener.