Search code examples
javascriptnode.jszipjszip

How to generate zip file using Buffer contents in node.js using JSZip?


I have an array of strings which should be written to a .txt file. Also I need to compress the resulting .txt file to .zip format using JSZip. At the client side, I was able to generate a 'text/plain' Blob using this array of strings and then I compressed this Blob to .zip format using JSZip. I need to do the same on the server side using node.js, but I realized that Blob is not available in node.js. I tried using 'Buffer' instead of Blob, and I got a binary file compressed as .zip; I am a beginner with node.js and couldn't understand the concepts of Buffer. Can I create a Blob in node.js? or Can I perform the same operations with node.js Buffer?

At the client side I can generate the zip file from Blob contents like this,

//stringsArray is an array of strings
var blob = new Blob( stringsArray, { type: "text/plain" } );

var zip = new JSZip();
zip.file( 'file.txt' , blob );

zip.generateAsync( { type: 'blob', compression: 'DEFLATE' } )
.then( function( zipFile ){ 

    //do something with zipFile 

}, function( error ){ 

    console.log( 'Error in compression' );

} );

How can I do the same using Node.js?


Solution

  • I found a solution for this. In my code, I wasn't using the proper method to convert the array of strings to node.js buffer ( I wasn't able to compress the buffer using JSZip because the buffer was incorrect ). I tried the following code but it gave me an incorrect buffer,

    //stringsArray is an array of strings
    var buffer = Buffer.from( stringsArray );
    

    The proper way is that, we have to convert each string to buffer first and then create a new buffer by appending all these sub buffers. I have created a custom buffer builder which will build a node.js buffer by appending strings to it. Following is the new method I have tried, and it worked for me.

    var CustomBufferBuilder = function() {
    
        this.parts = [];
        this.totalLength = 0;
    
    }
    
    CustomBufferBuilder.prototype.append = function( part ) {
    
        var tempBuffer = Buffer.from( part );
        this.parts.push( tempBuffer );
        this.totalLength += tempBuffer.length;
        this.buffer = undefined;
    
    };
    
    CustomBufferBuilder.prototype.getBuffer = function() {
    
        if ( !this.buffer ) {
    
           this.buffer = Buffer.concat( this.parts, this.totalLength );
    
        }
        return this.buffer;
    
    };
    
    
    var customBufferBuilder = new CustomBufferBuilder();
    var stringsArray = [ 'hello ', 'world.', '\nThis ', 'is', ' a ', 'test.' ];//stringsArray is an array of strings
    var len = stringsArray.length;
    for( var i = 0; i< len; i++ ){
    
        customBufferBuilder.append( stringsArray[ i ] );
    
    }
    
    var bufferContent = customBufferBuilder.getBuffer();
    
    var zip = new JSZip();
    zip.file( 'test.txt', bufferContent, { binary : true } );
    zip.generateAsync( { type : "nodebuffer", compression: 'DEFLATE' } )
    .then( function callback( buffer ) {
    
        fs.writeFile( 'test.zip', buffer, function( err ){
    
            if( err ){
    
                //tasks to perform in case of error
    
            }
            else{
    
                //other logic
    
            }
    
        } );
    
    }, function( e ) {
    
        //tasks to perform in case of error
    
    } );
    

    As output, I got the zip file( test.zip ) and test.txt inside it. The test.txt file inside the zip file contains the following words, 'hello world.\nThis is a test.'.

    Thanks @BrahmaDev for spending time to look into my question :)