Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Created XLSX compression #220

Closed
SzaboAdamImre opened this issue May 5, 2015 · 14 comments
Closed

Created XLSX compression #220

SzaboAdamImre opened this issue May 5, 2015 · 14 comments

Comments

@SzaboAdamImre
Copy link

Hello!

I might be missing some functionality here, but I can't enable the compression on the files...
I'm using the node version of this library (https://www.npmjs.com/package/xlsx) to convert some server side data to XLSX, and serve it as downloadable file (without saving the file itself on the server side). The code I'm using:
(the callback function is a HAPI reply function)

var wopts = {bookType: 'xlsx', bookSST: false};
var binary = XLSX.write(workbook, wopts);
var response = callback(binary);
response.type('application/octet-stream');
response.header('Content-Disposition', 'attachment; filename="'   fileName   '.xlsx"');

This code works fine, the xlsx is available for download, and the data is correct.
The problem is that the file size is too big...
F.E a downloaded file is 1,3 MB.
I open that file in Excel, modify a small detail (f.e. modify a number), and the file size becomes 153 KB.

I have reproduced this with LibreOffice, and with the writeFile function as well.

What am I missing?

Thx in advance

@Siri0n
Copy link

Siri0n commented May 5, 2015

I could guess it's concerned with Shared String Table (ISO/IEC 29500-1 specification, p.18.4). In than case devs just should implement that mechanism in js-xlsx.

@SzaboAdamImre
Copy link
Author

Tried it with and without SST (bookSST true/false), no change
(also with xlsx, xlsb and xlsm mode - neither was good)

@SheetJSDev
Copy link
Contributor

@SzaboAdamImre @Siri0n the zip library is not compressing (it is storing the files as plaintext rather than using the DEFLATE algorithm). That option needs to be made available to the write functions

@SzaboAdamImre
Copy link
Author

@SheetJSDev
So it is not available in the current version?

@bchr02
Copy link

bchr02 commented Aug 6, 2015

@SzaboAdamImre Did you ever figure out how to compress your file? I am running into the same exact problem. Thanks.

@bchr02
Copy link

bchr02 commented Aug 6, 2015

@SzaboAdamImre @Siri0n @SheetJSDev

I created a pull request which will give us the ability to add a compression option.

Example usage:
XLSX.writeFile(wb, 'out.xlsx', {compression: 'DEFLATE'});

If you don't want to wait for the next version commit then just edit your xlsx.js file and replace the write_zip_type function with the updated one:

function write_zip_type(wb, opts) {
    var o = {}, z;
    opts = opts||{};
    z = write_zip(wb, opts);

    switch(opts.type) {
        case "base64": o.type = "base64"; if (typeof opts.compression === 'string') {o.compression = opts.compression;} break;
        case "binary": o.type = "string"; if (typeof opts.compression === 'string') {o.compression = opts.compression;} break;
        case "buffer": o.type = "nodebuffer"; if (typeof opts.compression === 'string') {o.compression = opts.compression;} break;
        case "file": o.type = "nodebuffer"; if (typeof opts.compression === 'string') {o.compression = opts.compression;} break;
        default: throw new Error("Unrecognized type "   opts.type);
    }

    if(opts.type === "file") {
        return _fs.writeFileSync(opts.file, z.generate(o));
    }
    else {
        return z.generate(o);
    }
}

@chk-
Copy link

chk- commented Nov 5, 2015

@bchr02 So many thanks, this is great!

@gtskaushik
Copy link

Hi All,
I am facing the same issue. The final file size is enormous. But on opening and saving the file again without any changes reduces it to normal size.

Please let me know whether this issue is fixed?

@reviewher
Copy link
Contributor

@gtskaushik it's not enabled by default, you have to pass the compression:true option to the write function:

var wopts = {bookType: 'xlsx', bookSST: true, compression:true};
var binary = XLSX.write(workbook, wopts);

@gtskaushik
Copy link

@reviewher Thanks for the immediate reply. I'm already using this library with compression option. But still the size is 30 MB. But when I open the file in Microsoft Excel and save it again , it becomes 6 MB

@reviewher
Copy link
Contributor

@gtskaushik can you share the code that generated the file?

@gtskaushik
Copy link

var wb = new Workbook()
var ws = {};
var range = {s: {c:0, r:0}, e: {c:0, r:0 }};
for(var R = 0; R !== data.length; R) {
for(var C = 0; C !== data[R].length; C) {
if(range.s.r > R) range.s.r = R;
if(range.s.c > C) range.s.c = C;
if(range.e.r < R) range.e.r = R;
if(range.e.c < C) range.e.c = C;
var cell = {v: data[R][C], s: {} };
if(cell.v === null) continue;
var cell_ref = XLSX.utils.encode_cell({c:C,r:R});

                //This is for the Header and timestamps cells
                if(R==0 || C==0 || C==1){
                    cell.s = {
                        "fill": {
                            "patternType": "solid",
                            "bgColor": {rgb:'003d79'},
                            "fgColor": {rgb:'003d79'}
                        },
                        "font": {
                            "color": {rgb:'ffffff'},
                            "bold": true
                        }
                    }
                }

                if(typeof cell.v === 'number') {
                    cell.t = 'n';
                    cell['s']['numFmt'] = "0.00"//Included Number Format
                }

                else if(typeof cell.v === 'boolean') cell.t = 'b';
                else if(cell.v instanceof Date) {
                    cell.t = 'n'; cell.z = XLSX.SSF._table[14];
                    cell.v = datenum(cell.v);
                }
                else cell.t = 's';

                ws[cell_ref] = cell;
            }
        }
        ws['!ref'] = XLSX.utils.encode_range(range)//Setting the reference range of the sheet

        ws['!cols'] = []
        data[0].forEach(function(header){ ws['!cols'].push({"wch": header.length}) })//Setting Dynamic column width

        ws['!freeze'] = { xSplit: "1", ySplit: "1", topLeftCell: "B2", activePane: "bottomRight", state: "frozen" }//Freezing the columns

       wb.SheetNames.push(ws_name);
        wb.Sheets[ws_name] = ws;

        var wopts = { bookType:'xlsx', bookSST:true, type: "binary",compression:true};

        return XLSX.write(wb,wopts);

@you96
Copy link

you96 commented May 18, 2018

@gtskaushik hello, got the same problem, did you fix this issue? many thanks:)

@shdb1993
Copy link

shdb1993 commented Jul 10, 2020

Same Problem Here.File Size is large on download but on resaving, the size of the file reduces.Please share the solution for this if anyone has come up with one

saarCiklum pushed a commit to Folcon/js-xlsx that referenced this issue Aug 17, 2020
- README and example cleanup
- basic XLSB and ODS write support
- flow typecheck for ODS file
  Note: xlsx.js flow fails: facebook/flow#380
- exposed jszip compression (fixes SheetJS#220, closes SheetJS#284)

README issues:

|  id  | author         | comment                                      |
|-----:|:---------------|:---------------------------------------------|
| SheetJS#202 | @sao93859      | closes SheetJS#202                                  |
| SheetJS#211 | @alexanderchan | closes SheetJS#211 corrected examples               |
| SheetJS#327 | @cskaandorp    | changed saveAs example to match write tests  |
| SheetJS#424 | @dskrvk        | added note about s2roa h/t @LeonardoPatignio |
| SheetJS#496 | @jimmywarting  | closes SheetJS#496 adapted rABS examples with rAAS  |

ODS file format issues:

|  id  | author         | comment                                      |
|-----:|:---------------|:---------------------------------------------|
| protobi#148 | @user4815162342| closes protobi#148 h/t @ziacik                      |
| protobi#166 | @paulproteus   | closes protobi#166 rudimentary ODS write support    |
| protobi#177 | @ziacik        | closes protobi#177                                  |
| protobi#179 | @ziacik        | closes protobi#179 use JSON when available          |
| SheetJS#317 | @ziacik        | closes SheetJS#317                                  |
| SheetJS#328 | @think01       | closes SheetJS#328                                  |
| SheetJS#383 | @mdamt         | closes SheetJS#383 duplicate cells should be copied |
| SheetJS#430 | @RB-Lab        | closes SheetJS#430                                  |
| SheetJS#546 | @lgodard       | closes SheetJS#546 thanks to other changes          |
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants