JSZip 解压时改变文件内容 (pdf)

JSZip Changes Contents of Files (pdf) While Decompressing

我正在使用 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,但我在浏览器中显示了不同的 Uint8Arrays。谁能告诉我为什么这些不同,以及如何让从 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>