javascript - JSZip 在解压缩时更改文件内容 (pdf)

标签 javascript zip compression filereader jszip

我使用 FileReader API 将输入文件的内容加载到浏览器内存中。这个 jsfiddle 包含一个工作示例: https://jsfiddle.net/qyh1s60d/

我将结果转换为 Uint8Array 并将其显示在 div 中:

<label for="file-pdf">select a pdf:</label>
<input type="file" id="file-pdf" name="files[]" />
<div id="result-pdf">
</div>

JS

document.getElementById('file-pdf').addEventListener('change', handlePdfSelect, false);
function handlePdfSelect(evt) {
    var files = evt.target.files; // FileList object
    var reader = new FileReader();
    reader.onload = (e)=>{
       var res = new Uint8Array(e.target.result);
       resultPdf.innerHTML = res.slice(0, 5)
    }

    reader.readAsArrayBuffer(files[0]);

  }

到目前为止一切顺利。 div 按预期显示数字数组。

接下来我想使用 JSZip 获取位于 zip 文件内的相同 pdf。这是 HTML:

label for="file-zip">select a zip:</label>
<input type="file" id="file-zip" name="files[]" />
<div id="result-zip">
</div>

还有JS

document.getElementById('file-zip').addEventListener('change', handleZipSelect, false); 

function handleZipSelect(evt) {
    var files = evt.target.files; // FileList object
    var reader = new FileReader();
    reader.onload = (e)=>{
       var res = new Uint8Array(e.target.result);
       JSZip.loadAsync(res).then(function(data){
       var pdfs = []       
        Object.keys(data['files']).forEach(f => {
                         if(/\.pdf$/.test(f)){
                             pdfs.push(data['files'][f])
                         }
        })
        var pdfcontents = pdfs[0]['_data']['compressedContent'].slice(0, 5)
        resultZip.innerHTML = pdfcontents;

       })

    }

    reader.readAsArrayBuffer(files[0]);


  }

即使我在这两个文件上传中使用相同的 pdf,我也会在浏览器中显示不同的 Uint8Array。谁能告诉我为什么这些不同,以及如何使从 zip 文件中获取的 pdf 数据看起来与直接以 pdf 形式上传时相同?

最佳答案

是的,这两个文件彼此不同,并且它们给出不同的Uint8Arrays,这是因为第一个是原始pdf文件,另一个是相同的pdf文件但处于压缩状态。

因此,如果您需要提取 pdf 文件的内容,则需要额外的一行代码来使用以下方法提取内容:async()

async(type[, onUpdate])

Return a Promise of the content in the asked type.

Possible values for type :

  • base64 : the result will be a string, the binary in a base64 form.
  • text (or string): the result will be an unicode string.
  • binarystring: the result will be a string in “binary” form, using 1 byte per char (2 bytes).
  • array: the result will be an Array of bytes (numbers between 0 and 255).
  • uint8array : the result will be a Uint8Array. This requires a compatible browser.
  • arraybuffer : the result will be a ArrayBuffer. This requires a compatible browser.
  • blob : the result will be a Blob. This requires a compatible browser.
  • nodebuffer : the result will be a nodejs Buffer. This requires nodejs.

Here the documentation on GitHub

这里How to read a file using jszip

工作示例: https://jsfiddle.net/e2Lxyrpn/

var resultPdf = document.getElementById('result-pdf');
var resultZip = document.getElementById('result-zip');
document.getElementById('file-pdf').addEventListener('change', handlePdfSelect, false);
function handlePdfSelect(evt) {
    var files = evt.target.files; // FileList object
    var reader = new FileReader();
    reader.onload = (e)=>{
       var res = new Uint8Array(e.target.result);
       
       resultPdf.innerHTML = res.slice(0, 5)
    }

    reader.readAsArrayBuffer(files[0]);
  
  }
  
document.getElementById('file-zip').addEventListener('change', handleZipSelect, false); 

function handleZipSelect(evt) {
    var files = evt.target.files; // FileList object
    var reader = new FileReader();
    reader.onload = (e)=>{
       var res = new Uint8Array(e.target.result);
       JSZip.loadAsync(res).then(function(data){
       var pdfs = []       
        Object.keys(data['files']).forEach(f => {
                         if(/\.pdf$/.test(f)){
                             pdfs.push(data['files'][f])
                         }
        });
        //>>>>>>>>------read the file Content --------
        pdfs[0].async('Uint8Array').then(function (fileData) {
							var allstring = fileData.slice(0, 5);
       						resultZip.innerHTML = allstring;
						});
        //--------------------------------------------
       
       })

    }

    reader.readAsArrayBuffer(files[0]);
    
  
  }
  
  console.log(JSZip)
  
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.2.2/jszip.min.js"></script>
<label for="file-pdf">select a pdf:</label>
<input type="file" id="file-pdf" name="files[]" />
<div id="result-pdf">
</div>
<br>
<br>
<br>
<br>
<label for="file-zip">select a zip containing the same pdf:</label>
<input type="file" id="file-zip" name="files[]" />
<div id="result-zip">
</div>

关于javascript - JSZip 在解压缩时更改文件内容 (pdf),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57991531/

相关文章:

php - 什么是 PHP 的 Memcache 中的压缩?

javascript - 如何分割一个字符串,然后将第二个字符串(链接)嵌入到第一个字符串中?

javascript - 在 Angular 2 应用程序上使用 Webpack 时,sourcemap 无法在 Firefox 上运行

javascript - 在 JavaScript 中,为什么 (undefined && true) 返回 undefined?

r - 如何在 R 中压缩多个 CSV 文件?

php - 提供本地json文件: how to cache

algorithm - Matlab中的放气算法

javascript - 将文本值保存到 ListView 并开始计时

linux - 问题,与 Zip4 扩展名、将标准输入内容定向到 zip 存档、使用 zip 以及使用 zipnotes 更改压缩文件名相关

javascript - 在客户端将大文件 (> 2GB) 压缩成 ZIP