egeriis / zipcelx

Turns JSON data into `.xlsx` files in the browser
MIT License
293 stars 89 forks source link

ES2015 class refactor #38

Open Radiergummi opened 6 years ago

Radiergummi commented 6 years ago

I've reworked zipcelx into a class since it fits better into our application workflow. Just leaving this here for reference in case this is useful to you.

Notably, the public API is split between analyze, build and download, the console calls are gone in favor of actual thrown errors and the lodash dependency was removed since it's really just a few lines of code that don't do anything special.
The workflow changes to the following:

import Spreadsheet from 'zipcelx';

try {
  const mySheet = new Spreadsheet( [ /* sheet data */ ] );
} catch ( error ) {
  console.error( `Could not create my sheet: ${error.message}` );
}

await mySheet.download( 'desired-filename-without-extension' );

console.log( 'file has been downloaded.' );

See the gist here.

Thank you for the library, it's coming in handy over here 😉

egeriis commented 6 years ago

Cool @Radiergummi

There are some clear benefits to this approach. One thing we could easily pull into the existing setup, is replacing console.error w/throwing errors. Good improvement alone.

I wonder what the file size would be if we compiled your code. Did you try that? 🙂

Radiergummi commented 6 years ago

@egeriis I didn't compile it standalone yet - I'm working on a single page, intranet ERP system, so a few KBs more or less don't really matter to me ;)

EDIT Depending on how you compile things though, I guess it will be pretty efficient. Classes are just syntactic sugar for regular object prototypes, and I don't think my approach is too bloated.

I'm currently also working on support for date and boolean cells (the latter working already) - they only require few lines.

Additionally, I've implemented a method to convert ordinary objects into tabular arrays:

[
  { foo: 'another', bar: 42, baz: new Date(), quz: true },
  { foo: 'pointless', bar: 43, baz: new Date('2012-03-04T05:04:33'), quz: false },
  { foo: 'string of text', bar: 44, baz: new Date('2013/05/05 13:12:11'), quz: false }
]
// becomes
[
  [ { value: 'foo', type: String }, { value: 'bar', type: String}, { value: 'baz', type: String }, { value: 'quz', type: String } ],
  [ { value: 'another', type: String }, { value: 42, type: Number }, { value: Mon May 07 2018 14:01:55 GMT+0200 (CEST), type: Date }, { value: true, type: Boolean } ],
  [ { value: 'pointless', type: String }, { value: 43, type: Number }, { value: Sun Mar 04 2012 05:04:33 GMT+0100 (CET, type: Date }, { value: false, type: Boolean } ],
  [ { value: 'string of text', type: String }, { value: 44, type: Number }, { value: Sun May 05 2013 13:12:11 GMT+0200, type: Date }, { value: false, type: Boolean } ],
]

This method can handle single objects instead of arrays and all supported value types.

As soon as everything works out fine, I'll update this issue with my final code. If all of this is too much for the scope of this lib, that's fine too - I just don't see no value in keeping these trivial improvements locked up.

Radiergummi commented 6 years ago

Okay, see the updated version here. Still having problems with date cells tho, any idea?

egeriis commented 6 years ago

Classes are syntactic sugar, but they will produce some boilerplate code when they're transpiled 🙂

Unfortunately I haven't looked into what format date needs to be presented in. The s="3" is that some kind of reference?

Radiergummi commented 6 years ago

Yup, as far as I found any resources on the format, the s="whatever" attribute refers to a specific format ID, which seems to be required to display dates, since Excel works with those cringeworthy 1904-dates internally... It's quite a big mess, actually 😄

egeriis commented 6 years ago

Appears to be some docs here https://msdn.microsoft.com/en-us/library/office/documentformat.openxml.spreadsheet.cell.aspx

The index of this cell's style. Style records are stored in the Styles Part. The possible values for this attribute are defined by the W3C XML Schema unsignedInt datatype.

So it's likely a reference to a style specified elsewhere.

bragma commented 6 years ago

Hi, I'd like to use this lib but I really need dates support. I was about to start to work on a PR when I stumbled on this. How are you faring with dates? Thanks

Radiergummi commented 6 years ago

@bragma Sorry, I'm of no help here. Since my project was due, I resorted to just inserting ISO dates which can be sorted using the standard sorter in Excel, since I was running out of time. I'll try to help you if you've got any questions while implementing though!

bragma commented 6 years ago

@Radiergummi I may have the same problem, I need something pretty fast. I expected the change to be rather quick to do, but I've found out that just setting a style is not enough, a style document is needed. This is a bit disappointing...

Radiergummi commented 6 years ago

Yeah, it's massively complex to do. I eventually just gave up. I'd really suggest using ISO dates. You can always sell them to your customers as being an accurate, sortable date-time representation 😉

egeriis commented 6 years ago

Yeah, the Open Office format is not necessarily easy to work with. I understand why, but I remember the initial work on zipcelx and how much time we spend tearing the xlsx files apart 🙂