Files
cut-abstractions/tests/dev1/dataHandle/common/zip.ts
2025-07-22 18:22:31 +08:00

152 lines
3.1 KiB
TypeScript

// import JsZip from 'jszip';
import type { DeflateOptions } from 'fflate'
import { Zip, ZipDeflate, strToU8 } from 'fflate'
import { getFileExt } from './file'
export class FileInfo
{
name: string
content: string | Blob | Uint8Array
encode: string = 'UTF-8'
isBase64 = false
binary = false
constructor(name, text, isBase64 = false)
{
this.name = name
this.content = text
this.isBase64 = isBase64
}
}
export abstract class ZipProvider
{
// abstract loadAsync(file: File): Promise<void>;
protected files: FileInfo[] = []
addFile(file: FileInfo)
{
this.files.push(file)
}
abstract saveAsync(): Promise<Blob>
}
// export class JsZipProvider extends ZipProvider
// {
// private ctx = new JsZip();
// // async loadAsync(file: File): Promise<void>
// // {
// // await this.ctx.loadAsync(file);
// // }
// async saveAsync(): Promise<Blob>
// {
// for (const file of this.files)
// {
// this.ctx.file(file.name, file.content, {
// createFolders: true,
// base64: file.isBase64,
// binary: file.binary,
// compression: "DEFLATE",
// });
// }
// return await this.ctx.generateAsync({ type: 'blob' });
// }
// }
export class FflateZipProvider extends ZipProvider
{
private ctx = new Zip()
private task: Promise<Blob>
constructor()
{
super()
this.task = new Promise<Blob>((resolve, reject) =>
{
let result = []
this.ctx.ondata = (err, data, final) =>
{
if (!err)
{
result.push(data)
if (final)
{
resolve(new Blob(result, { type: 'application/zip' }))
}
} else
{
reject()
}
}
})
}
async saveAsync(): Promise<Blob>
{
for (const file of this.files)
{
let data: Uint8Array
if (file.content instanceof Blob)
{
// console.log(file.name);
let buffer = await file.content.arrayBuffer()
// console.log('buffer', buffer);
data = new Uint8Array(buffer)
} else if (file.content instanceof Uint8Array)
{
data = file.content
}
else if (file.isBase64)
{
data = new Uint8Array(atob(file.content).split('').map((c) =>
{
return c.charCodeAt(0)
}))
} else
{
data = strToU8(file.content)
}
let zipInput = new ZipDeflate(file.name, this.getOptionByExt(file.name))
this.ctx.add(zipInput)
zipInput.push(data, true)
}
this.ctx.end()
return this.task
}
getOptionByExt(fileName: string)
{
let option: DeflateOptions = {
level: 6,
// mem: 12
}
let ext = getFileExt(fileName)
if (ext !== null)
{
switch (ext)
{
case 'bmp':
option.level = 1
option.mem = 0
break
case 'jpg':
case 'jpeg':
option.level = 1
break
case 'png':
option.level = 0
break
}
}
return option
}
}
export const DefaultZipProvider = () => new FflateZipProvider()