Zipjs (#7)
* Remplacement de unzipit par zip.js * Générer un fichier qui est valide et s'ouvre dans LibreOffice * blip bloop, smaller browser bundle * uninstall xlsx
This commit is contained in:
parent
05190774c4
commit
a3a2393217
2
.gitignore
vendored
2
.gitignore
vendored
@ -3,3 +3,5 @@ node_modules/
|
||||
build/*
|
||||
|
||||
.~lock*
|
||||
|
||||
stats.html
|
||||
382
package-lock.json
generated
382
package-lock.json
generated
@ -9,8 +9,7 @@
|
||||
"version": "0.10.0",
|
||||
"dependencies": {
|
||||
"@xmldom/xmldom": "^0.8.10",
|
||||
"unzipit": "^1.4.3",
|
||||
"xlsx": "^0.18.5"
|
||||
"@zip.js/zip.js": "^2.7.57"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
@ -22,6 +21,7 @@
|
||||
"rollup": "^4.18.0",
|
||||
"rollup-plugin-css-only": "^4.5.2",
|
||||
"rollup-plugin-svelte": "^7.1.6",
|
||||
"rollup-plugin-visualizer": "^5.14.0",
|
||||
"sass": "^1.58.3",
|
||||
"svelte": "^4.2.9",
|
||||
"svelte-preprocess": "^5.1.3"
|
||||
@ -611,6 +611,17 @@
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@zip.js/zip.js": {
|
||||
"version": "2.7.57",
|
||||
"resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.57.tgz",
|
||||
"integrity": "sha512-BtonQ1/jDnGiMed6OkV6rZYW78gLmLswkHOzyMrMb+CAR7CZO8phOHO6c2qw6qb1g1betN7kwEHhhZk30dv+NA==",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"bun": ">=0.7.0",
|
||||
"deno": ">=1.0.0",
|
||||
"node": ">=16.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/abbrev": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||
@ -650,15 +661,6 @@
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/adler-32": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz",
|
||||
"integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/agent-base": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||
@ -1072,19 +1074,6 @@
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/cfb": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz",
|
||||
"integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"adler-32": "~1.3.0",
|
||||
"crc-32": "~1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
@ -1270,15 +1259,6 @@
|
||||
"@types/estree": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/codepage": {
|
||||
"version": "1.15.0",
|
||||
"resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz",
|
||||
"integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
@ -1382,18 +1362,6 @@
|
||||
"node": ">= 0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/crc-32": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
|
||||
"integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"crc32": "bin/crc32.njs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/css-tree": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
|
||||
@ -1449,6 +1417,16 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/define-lazy-prop": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
|
||||
"integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/define-properties": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
|
||||
@ -1711,15 +1689,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/frac": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz",
|
||||
"integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/fs-minipass": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
|
||||
@ -2323,6 +2292,22 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/is-docker": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
|
||||
"integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"is-docker": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-extglob": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
@ -2440,6 +2425,19 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-wsl": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
|
||||
"integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-docker": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
@ -2944,6 +2942,24 @@
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/open": {
|
||||
"version": "8.4.2",
|
||||
"resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz",
|
||||
"integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"define-lazy-prop": "^2.0.0",
|
||||
"is-docker": "^2.1.1",
|
||||
"is-wsl": "^2.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/opener": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
|
||||
@ -3428,6 +3444,60 @@
|
||||
"node": ">= 8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup-plugin-visualizer": {
|
||||
"version": "5.14.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.14.0.tgz",
|
||||
"integrity": "sha512-VlDXneTDaKsHIw8yzJAFWtrzguoJ/LnQ+lMpoVfYJ3jJF4Ihe5oYLAqLklIK/35lgUY+1yEzCkHyZ1j4A5w5fA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"open": "^8.4.0",
|
||||
"picomatch": "^4.0.2",
|
||||
"source-map": "^0.7.4",
|
||||
"yargs": "^17.5.1"
|
||||
},
|
||||
"bin": {
|
||||
"rollup-plugin-visualizer": "dist/bin/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rolldown": "1.x",
|
||||
"rollup": "2.x || 3.x || 4.x"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rolldown": {
|
||||
"optional": true
|
||||
},
|
||||
"rollup": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/rollup-plugin-visualizer/node_modules/picomatch": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
|
||||
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup-plugin-visualizer/node_modules/source-map": {
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
|
||||
"integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup/node_modules/fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
@ -3719,18 +3789,6 @@
|
||||
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ssf": {
|
||||
"version": "0.11.2",
|
||||
"resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz",
|
||||
"integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"frac": "~1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/stack-utils": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
|
||||
@ -4131,17 +4189,6 @@
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/unzipit": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/unzipit/-/unzipit-1.4.3.tgz",
|
||||
"integrity": "sha512-gsq2PdJIWWGhx5kcdWStvNWit9FVdTewm4SEG7gFskWs+XCVaULt9+BwuoBtJiRE8eo3L1IPAOrbByNLtLtIlg==",
|
||||
"dependencies": {
|
||||
"uzip-module": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/url-join": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
|
||||
@ -4154,11 +4201,6 @@
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/uzip-module": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/uzip-module/-/uzip-module-1.0.3.tgz",
|
||||
"integrity": "sha512-AMqwWZaknLM77G+VPYNZLEruMGWGzyigPK3/Whg99B3S6vGHuqsyl5ZrOv1UUF3paGK1U6PM0cnayioaryg/fA=="
|
||||
},
|
||||
"node_modules/validate-npm-package-license": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
|
||||
@ -4277,24 +4319,6 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/wmf": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz",
|
||||
"integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/word": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz",
|
||||
"integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
@ -4426,27 +4450,6 @@
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/xlsx": {
|
||||
"version": "0.18.5",
|
||||
"resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz",
|
||||
"integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"adler-32": "~1.3.0",
|
||||
"cfb": "~1.2.1",
|
||||
"codepage": "~1.15.0",
|
||||
"crc-32": "~1.2.1",
|
||||
"ssf": "~0.11.2",
|
||||
"wmf": "~1.0.1",
|
||||
"word": "~0.3.0"
|
||||
},
|
||||
"bin": {
|
||||
"xlsx": "bin/xlsx.njs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
@ -4922,6 +4925,11 @@
|
||||
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
|
||||
"integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw=="
|
||||
},
|
||||
"@zip.js/zip.js": {
|
||||
"version": "2.7.57",
|
||||
"resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.57.tgz",
|
||||
"integrity": "sha512-BtonQ1/jDnGiMed6OkV6rZYW78gLmLswkHOzyMrMb+CAR7CZO8phOHO6c2qw6qb1g1betN7kwEHhhZk30dv+NA=="
|
||||
},
|
||||
"abbrev": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||
@ -4950,11 +4958,6 @@
|
||||
"acorn": "^8.11.0"
|
||||
}
|
||||
},
|
||||
"adler-32": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz",
|
||||
"integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A=="
|
||||
},
|
||||
"agent-base": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||
@ -5265,15 +5268,6 @@
|
||||
"nofilter": "^3.1.0"
|
||||
}
|
||||
},
|
||||
"cfb": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz",
|
||||
"integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==",
|
||||
"requires": {
|
||||
"adler-32": "~1.3.0",
|
||||
"crc-32": "~1.2.0"
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
@ -5419,11 +5413,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"codepage": {
|
||||
"version": "1.15.0",
|
||||
"resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz",
|
||||
"integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA=="
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
@ -5511,11 +5500,6 @@
|
||||
"integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==",
|
||||
"dev": true
|
||||
},
|
||||
"crc-32": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
|
||||
"integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ=="
|
||||
},
|
||||
"css-tree": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
|
||||
@ -5559,6 +5543,12 @@
|
||||
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
|
||||
"dev": true
|
||||
},
|
||||
"define-lazy-prop": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
|
||||
"integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
|
||||
"dev": true
|
||||
},
|
||||
"define-properties": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
|
||||
@ -5749,11 +5739,6 @@
|
||||
"integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==",
|
||||
"dev": true
|
||||
},
|
||||
"frac": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz",
|
||||
"integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA=="
|
||||
},
|
||||
"fs-minipass": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
|
||||
@ -6207,6 +6192,12 @@
|
||||
"integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
|
||||
"dev": true
|
||||
},
|
||||
"is-docker": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
|
||||
"integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
|
||||
"dev": true
|
||||
},
|
||||
"is-extglob": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
@ -6291,6 +6282,15 @@
|
||||
"integrity": "sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==",
|
||||
"dev": true
|
||||
},
|
||||
"is-wsl": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
|
||||
"integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-docker": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
@ -6666,6 +6666,17 @@
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"open": {
|
||||
"version": "8.4.2",
|
||||
"resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz",
|
||||
"integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"define-lazy-prop": "^2.0.0",
|
||||
"is-docker": "^2.1.1",
|
||||
"is-wsl": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"opener": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
|
||||
@ -7013,6 +7024,32 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"rollup-plugin-visualizer": {
|
||||
"version": "5.14.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.14.0.tgz",
|
||||
"integrity": "sha512-VlDXneTDaKsHIw8yzJAFWtrzguoJ/LnQ+lMpoVfYJ3jJF4Ihe5oYLAqLklIK/35lgUY+1yEzCkHyZ1j4A5w5fA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"open": "^8.4.0",
|
||||
"picomatch": "^4.0.2",
|
||||
"source-map": "^0.7.4",
|
||||
"yargs": "^17.5.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"picomatch": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
|
||||
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
|
||||
"dev": true
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
|
||||
"integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"run-parallel": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
||||
@ -7224,14 +7261,6 @@
|
||||
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
|
||||
"dev": true
|
||||
},
|
||||
"ssf": {
|
||||
"version": "0.11.2",
|
||||
"resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz",
|
||||
"integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==",
|
||||
"requires": {
|
||||
"frac": "~1.1.2"
|
||||
}
|
||||
},
|
||||
"stack-utils": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
|
||||
@ -7495,14 +7524,6 @@
|
||||
"qs": "^6.4.0"
|
||||
}
|
||||
},
|
||||
"unzipit": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/unzipit/-/unzipit-1.4.3.tgz",
|
||||
"integrity": "sha512-gsq2PdJIWWGhx5kcdWStvNWit9FVdTewm4SEG7gFskWs+XCVaULt9+BwuoBtJiRE8eo3L1IPAOrbByNLtLtIlg==",
|
||||
"requires": {
|
||||
"uzip-module": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"url-join": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
|
||||
@ -7515,11 +7536,6 @@
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||
"dev": true
|
||||
},
|
||||
"uzip-module": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/uzip-module/-/uzip-module-1.0.3.tgz",
|
||||
"integrity": "sha512-AMqwWZaknLM77G+VPYNZLEruMGWGzyigPK3/Whg99B3S6vGHuqsyl5ZrOv1UUF3paGK1U6PM0cnayioaryg/fA=="
|
||||
},
|
||||
"validate-npm-package-license": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
|
||||
@ -7619,16 +7635,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"wmf": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz",
|
||||
"integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw=="
|
||||
},
|
||||
"word": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz",
|
||||
"integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA=="
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
@ -7728,20 +7734,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"xlsx": {
|
||||
"version": "0.18.5",
|
||||
"resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz",
|
||||
"integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==",
|
||||
"requires": {
|
||||
"adler-32": "~1.3.0",
|
||||
"cfb": "~1.2.1",
|
||||
"codepage": "~1.15.0",
|
||||
"crc-32": "~1.2.1",
|
||||
"ssf": "~0.11.2",
|
||||
"wmf": "~1.0.1",
|
||||
"word": "~0.3.0"
|
||||
}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
|
||||
@ -21,13 +21,13 @@
|
||||
"rollup": "^4.18.0",
|
||||
"rollup-plugin-css-only": "^4.5.2",
|
||||
"rollup-plugin-svelte": "^7.1.6",
|
||||
"rollup-plugin-visualizer": "^5.14.0",
|
||||
"sass": "^1.58.3",
|
||||
"svelte": "^4.2.9",
|
||||
"svelte-preprocess": "^5.1.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@xmldom/xmldom": "^0.8.10",
|
||||
"unzipit": "^1.4.3",
|
||||
"xlsx": "^0.18.5"
|
||||
"@zip.js/zip.js": "^2.7.57"
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import commonjs from '@rollup/plugin-commonjs';
|
||||
import terser from '@rollup/plugin-terser';
|
||||
import css from 'rollup-plugin-css-only';
|
||||
import sveltePreprocess from 'svelte-preprocess'
|
||||
import { visualizer } from "rollup-plugin-visualizer";
|
||||
|
||||
const production = !process.env.ROLLUP_WATCH;
|
||||
|
||||
@ -37,6 +38,7 @@ export default {
|
||||
}),
|
||||
commonjs(),
|
||||
|
||||
visualizer(),
|
||||
// If we're building for production (npm run build
|
||||
// instead of npm run dev), minify
|
||||
//production && terser()
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<script>
|
||||
//@ts-check
|
||||
|
||||
import {tableRawContentToObjects, tableWithoutEmptyRows, getODSTableRawContent, getXLSXTableRawContent} from './browser.js'
|
||||
import {tableRawContentToObjects, tableWithoutEmptyRows, getODSTableRawContent, getXLSXTableRawContent, createOdsFile} from './browser.js'
|
||||
|
||||
const ODS_TYPE = "application/vnd.oasis.opendocument.spreadsheet";
|
||||
const XLSX_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||
@ -31,6 +31,9 @@
|
||||
$: tableObjectSheets = tableRawContent && tableRawContent.then(tableWithoutEmptyRows).then(tableRawContentToObjects) || []
|
||||
$: Promise.resolve(tableObjectSheets).then(x => console.log('tableObjectSheets', x))
|
||||
|
||||
// ligne inutile qui utilise createOdsFile pour l'importer dans le bundle
|
||||
$: tableRawContent && tableRawContent.then(createOdsFile).then(ab => console.log('length', ab.byteLength))
|
||||
|
||||
</script>
|
||||
|
||||
<h1>Import fichier .ods et .xslx</h1>
|
||||
|
||||
@ -5,6 +5,10 @@ import {
|
||||
_getXLSXTableRawContent
|
||||
} from './shared.js'
|
||||
|
||||
import {_createOdsFile} from './createOdsFile.js'
|
||||
|
||||
/** @import {SheetCellRawContent, SheetName, SheetRawContent} from './types.js' */
|
||||
|
||||
|
||||
function parseXML(str){
|
||||
return (new DOMParser()).parseFromString(str, 'application/xml');
|
||||
@ -27,7 +31,26 @@ export function getXLSXTableRawContent(xlsxArrBuff){
|
||||
}
|
||||
|
||||
|
||||
export {createOdsFile} from './createOdsFile.js'
|
||||
/** @type { typeof DOMImplementation.prototype.createDocument } */
|
||||
const createDocument = function createDocument(...args){
|
||||
// @ts-ignore
|
||||
return document.implementation.createDocument(...args)
|
||||
}
|
||||
|
||||
const serializer = new XMLSerializer()
|
||||
|
||||
/** @type { typeof XMLSerializer.prototype.serializeToString } */
|
||||
const serializeToString = function serializeToString(node){
|
||||
return serializer.serializeToString(node)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Map<SheetName, SheetRawContent>} sheetsData
|
||||
*/
|
||||
export function createOdsFile(sheetsData){
|
||||
return _createOdsFile(sheetsData, createDocument, serializeToString)
|
||||
}
|
||||
|
||||
|
||||
export {
|
||||
// table-level exports
|
||||
|
||||
@ -1,24 +1,161 @@
|
||||
//@ts-check
|
||||
import { ZipWriter, BlobWriter, TextReader } from '@zip.js/zip.js';
|
||||
|
||||
import {write, utils} from 'xlsx'
|
||||
import {tableRawContentToValues} from './shared.js'
|
||||
/** @import {SheetCellRawContent, SheetName, SheetRawContent} from './types.js' */
|
||||
|
||||
/** @import {SheetName, SheetRawContent} from './types.js' */
|
||||
const stylesXml = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<office:document-styles
|
||||
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
|
||||
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
|
||||
office:version="1.2">
|
||||
<office:styles/>
|
||||
<office:automatic-styles/>
|
||||
<office:master-styles/>
|
||||
</office:document-styles>`;
|
||||
|
||||
const manifestXml = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<manifest:manifest manifest:version="1.2" xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0">
|
||||
<manifest:file-entry manifest:media-type="application/vnd.oasis.opendocument.spreadsheet" manifest:full-path="/"/>
|
||||
<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="content.xml"/>
|
||||
<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="styles.xml"/>
|
||||
</manifest:manifest>`;
|
||||
|
||||
/**
|
||||
* Crée un fichier .ods à partir d'un Map de feuilles de calcul
|
||||
* @param {Map<SheetName, SheetRawContent>} sheetsData
|
||||
* @param {typeof DOMImplementation.prototype.createDocument} createDocument
|
||||
* @param {typeof XMLSerializer.prototype.serializeToString} serializeToString
|
||||
* @returns {Promise<ArrayBuffer>}
|
||||
*/
|
||||
export async function createOdsFile(sheetsData) {
|
||||
const workbook = utils.book_new();
|
||||
export async function _createOdsFile(sheetsData, createDocument, serializeToString) {
|
||||
// Create a new zip writer
|
||||
const zipWriter = new ZipWriter(new BlobWriter('application/vnd.oasis.opendocument.spreadsheet'));
|
||||
|
||||
const sheetsDataValues = tableRawContentToValues(sheetsData)
|
||||
zipWriter.add(
|
||||
"mimetype",
|
||||
new TextReader("application/vnd.oasis.opendocument.spreadsheet"),
|
||||
{
|
||||
compressionMethod: 0,
|
||||
level: 0,
|
||||
dataDescriptor: false,
|
||||
extendedTimestamp: false,
|
||||
}
|
||||
);
|
||||
|
||||
for(const [sheetName, table] of sheetsDataValues){
|
||||
const worksheet = utils.aoa_to_sheet(table);
|
||||
utils.book_append_sheet(workbook, worksheet, sheetName);
|
||||
const contentXml = generateContentFileXMLString(sheetsData, createDocument, serializeToString);
|
||||
zipWriter.add("content.xml", new TextReader(contentXml), {level: 9});
|
||||
|
||||
zipWriter.add("styles.xml", new TextReader(stylesXml));
|
||||
|
||||
zipWriter.add('META-INF/manifest.xml', new TextReader(manifestXml));
|
||||
|
||||
// Close the zip writer and get the ArrayBuffer
|
||||
const zipFile = await zipWriter.close();
|
||||
return zipFile.arrayBuffer();
|
||||
}
|
||||
|
||||
return write(workbook, {bookType: 'ods', type: 'array'});
|
||||
|
||||
/**
|
||||
* Generate the content.xml file with spreadsheet data
|
||||
* @param {Map<SheetName, SheetRawContent>} sheetsData
|
||||
* @param {typeof DOMImplementation.prototype.createDocument} createDocument
|
||||
* @param {typeof XMLSerializer.prototype.serializeToString} serializeToString
|
||||
* @returns {string}
|
||||
*/
|
||||
function generateContentFileXMLString(sheetsData, createDocument, serializeToString) {
|
||||
const doc = createDocument('urn:oasis:names:tc:opendocument:xmlns:office:1.0', 'office:document-content');
|
||||
const root = doc.documentElement;
|
||||
|
||||
// Set up namespaces
|
||||
root.setAttribute('xmlns:table', 'urn:oasis:names:tc:opendocument:xmlns:table:1.0');
|
||||
root.setAttribute('xmlns:text', 'urn:oasis:names:tc:opendocument:xmlns:text:1.0');
|
||||
root.setAttribute('xmlns:style', 'urn:oasis:names:tc:opendocument:xmlns:style:1.0');
|
||||
root.setAttribute('xmlns:number', 'urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0');
|
||||
root.setAttribute('xmlns:fo', 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0');
|
||||
root.setAttribute('office:version', '1.2');
|
||||
|
||||
const bodyNode = doc.createElement('office:body');
|
||||
root.appendChild(bodyNode);
|
||||
|
||||
const spreadsheetNode = doc.createElement('office:spreadsheet');
|
||||
bodyNode.appendChild(spreadsheetNode);
|
||||
|
||||
// Iterate through sheets
|
||||
sheetsData.forEach((sheetData, sheetName) => {
|
||||
const tableNode = doc.createElement('table:table');
|
||||
tableNode.setAttribute('table:name', sheetName);
|
||||
spreadsheetNode.appendChild(tableNode);
|
||||
|
||||
const columnNode = doc.createElement('table:table-column');
|
||||
tableNode.appendChild(columnNode);
|
||||
|
||||
// Iterate through rows
|
||||
sheetData.forEach((row) => {
|
||||
const rowNode = doc.createElement('table:table-row');
|
||||
tableNode.appendChild(rowNode);
|
||||
|
||||
// Iterate through cells in row
|
||||
row.forEach((cell) => {
|
||||
const cellNode = doc.createElement('table:table-cell');
|
||||
const cellType = convertCellType(cell.type);
|
||||
cellNode.setAttribute('office:value-type', cellType);
|
||||
|
||||
// Add value attribute based on type
|
||||
if (cell.value !== null && cell.value !== undefined) {
|
||||
switch (cellType) {
|
||||
case 'float':
|
||||
cellNode.setAttribute('office:value', cell.value.toString());
|
||||
break;
|
||||
case 'percentage':
|
||||
cellNode.setAttribute('office:value', cell.value.toString());
|
||||
cellNode.setAttribute('office:value-type', 'percentage');
|
||||
break;
|
||||
case 'date':
|
||||
cellNode.setAttribute('office:date-value', cell.value.toString());
|
||||
break;
|
||||
case 'boolean':
|
||||
cellNode.setAttribute('office:boolean-value', cell.value ? 'true' : 'false');
|
||||
break;
|
||||
default:
|
||||
const textNode = doc.createElement('text:p');
|
||||
textNode.textContent = cell.value.toString();
|
||||
cellNode.appendChild(textNode);
|
||||
break;
|
||||
}
|
||||
|
||||
if (cellType !== 'string') {
|
||||
const textNode = doc.createElement('text:p');
|
||||
textNode.textContent = cell.value.toString();
|
||||
cellNode.appendChild(textNode);
|
||||
}
|
||||
}
|
||||
|
||||
rowNode.appendChild(cellNode);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return serializeToString(doc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert cell type to OpenDocument format type
|
||||
* @param {SheetCellRawContent['type']} type
|
||||
* @returns {SheetCellRawContent['type']}
|
||||
*/
|
||||
function convertCellType(type) {
|
||||
const typeMap = {
|
||||
'float': 'float',
|
||||
'percentage': 'percentage',
|
||||
'currency': 'currency',
|
||||
'date': 'date',
|
||||
'time': 'time',
|
||||
'boolean': 'boolean',
|
||||
'string': 'string',
|
||||
'n': 'float',
|
||||
's': 'string',
|
||||
'd': 'date',
|
||||
'b': 'boolean'
|
||||
};
|
||||
return typeMap[type] || 'string';
|
||||
}
|
||||
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
//@ts-check
|
||||
|
||||
import {DOMParser} from '@xmldom/xmldom'
|
||||
import {DOMParser, DOMImplementation, XMLSerializer} from '@xmldom/xmldom'
|
||||
|
||||
import {
|
||||
_getODSTableRawContent,
|
||||
_getXLSXTableRawContent
|
||||
} from './shared.js'
|
||||
import { _createOdsFile } from './createOdsFile.js'
|
||||
|
||||
/** @import {SheetCellRawContent, SheetName, SheetRawContent} from './types.js' */
|
||||
|
||||
|
||||
function parseXML(str){
|
||||
@ -29,7 +32,27 @@ export function getXLSXTableRawContent(xlsxArrBuff){
|
||||
return _getXLSXTableRawContent(xlsxArrBuff, parseXML)
|
||||
}
|
||||
|
||||
export {createOdsFile} from './createOdsFile.js'
|
||||
const implementation = new DOMImplementation()
|
||||
|
||||
/** @type { typeof DOMImplementation.prototype.createDocument } */
|
||||
const createDocument = function createDocument(...args){
|
||||
// @ts-ignore
|
||||
return implementation.createDocument(...args)
|
||||
}
|
||||
|
||||
const serializer = new XMLSerializer()
|
||||
|
||||
/** @type { typeof XMLSerializer.prototype.serializeToString } */
|
||||
const serializeToString = function serializeToString(node){
|
||||
return serializer.serializeToString(node)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Map<SheetName, SheetRawContent>} sheetsData
|
||||
*/
|
||||
export function createOdsFile(sheetsData){
|
||||
return _createOdsFile(sheetsData, createDocument, serializeToString)
|
||||
}
|
||||
|
||||
export {
|
||||
// table-level exports
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
//@ts-check
|
||||
import { unzip } from 'unzipit';
|
||||
import { Uint8ArrayReader, ZipReader, TextWriter } from '@zip.js/zip.js';
|
||||
|
||||
/** @import {Entry} from '@zip.js/zip.js'*/
|
||||
/** @import {SheetName, SheetRawContent, SheetRowRawContent, SheetCellRawContent} from './types.js' */
|
||||
|
||||
|
||||
// https://dom.spec.whatwg.org/#interface-node
|
||||
const TEXT_NODE = 3
|
||||
|
||||
@ -48,11 +50,30 @@ function extraxtODSCellText(cell) {
|
||||
* @returns {Promise<Map<SheetName, SheetRawContent>>}
|
||||
*/
|
||||
export async function _getODSTableRawContent(arrayBuffer, parseXML) {
|
||||
const zip = await unzip(arrayBuffer);
|
||||
const entries = zip.entries;
|
||||
const zipDataReader = new Uint8ArrayReader(new Uint8Array(arrayBuffer));
|
||||
const zipReader = new ZipReader(zipDataReader);
|
||||
const zipEntries = await zipReader.getEntries()
|
||||
await zipReader.close();
|
||||
|
||||
/** @type {Map<Entry['filename'], Entry>} */
|
||||
const entryByFilename = new Map()
|
||||
for(const entry of zipEntries){
|
||||
const filename = entry.filename
|
||||
entryByFilename.set(filename, entry)
|
||||
}
|
||||
|
||||
const contentXmlEntry = entryByFilename.get('content.xml')
|
||||
|
||||
if(!contentXmlEntry){
|
||||
throw new TypeError(`entry 'content.xml' manquante dans le zip`)
|
||||
}
|
||||
|
||||
// Extract the content.xml file which contains the spreadsheet data
|
||||
const contentXml = await entries['content.xml'].text();
|
||||
|
||||
//@ts-ignore
|
||||
const contentXml = await contentXmlEntry.getData(new TextWriter());
|
||||
//console.log('contentXml', contentXml);
|
||||
|
||||
const contentDoc = parseXML(contentXml);
|
||||
|
||||
const tableMap = new Map();
|
||||
@ -109,29 +130,61 @@ export async function _getODSTableRawContent(arrayBuffer, parseXML) {
|
||||
* @returns {Promise<Map<SheetName, SheetRawContent>>}
|
||||
*/
|
||||
export async function _getXLSXTableRawContent(arrayBuffer, parseXML) {
|
||||
const zip = await unzip(arrayBuffer);
|
||||
const entries = zip.entries;
|
||||
const zipDataReader = new Uint8ArrayReader(new Uint8Array(arrayBuffer));
|
||||
const zipReader = new ZipReader(zipDataReader);
|
||||
const zipEntries = await zipReader.getEntries()
|
||||
await zipReader.close();
|
||||
|
||||
/** @type {Map<Entry['filename'], Entry>} */
|
||||
const entryByFilename = new Map()
|
||||
for(const entry of zipEntries){
|
||||
const filename = entry.filename
|
||||
entryByFilename.set(filename, entry)
|
||||
}
|
||||
|
||||
const sharedStringsEntry = entryByFilename.get('xl/sharedStrings.xml')
|
||||
|
||||
if(!sharedStringsEntry){
|
||||
throw new TypeError(`entry 'xl/sharedStrings.xml' manquante dans le zip`)
|
||||
}
|
||||
|
||||
//@ts-ignore
|
||||
const sharedStringsXml = await sharedStringsEntry.getData(new TextWriter());
|
||||
|
||||
const sharedStringsXml = await entries['xl/sharedStrings.xml'].text();
|
||||
const sharedStringsDoc = parseXML(sharedStringsXml);
|
||||
const sharedStrings = Array.from(sharedStringsDoc.getElementsByTagName('sst')[0].getElementsByTagName('si')).map(si => si.textContent);
|
||||
|
||||
// Get sheet names and their corresponding XML files
|
||||
const workbookXml = await entries['xl/workbook.xml'].text();
|
||||
const workbookEntry = entryByFilename.get('xl/workbook.xml')
|
||||
|
||||
if(!workbookEntry){
|
||||
throw new TypeError(`entry 'xl/workbook.xml' manquante dans le zip`)
|
||||
}
|
||||
|
||||
//@ts-ignore
|
||||
const workbookXml = await workbookEntry.getData(new TextWriter());
|
||||
const workbookDoc = parseXML(workbookXml);
|
||||
const sheets = Array.from(workbookDoc.getElementsByTagName('sheets')[0].getElementsByTagName('sheet'));
|
||||
const sheetNames = sheets.map(sheet => sheet.getAttribute('name'));
|
||||
const sheetIds = sheets.map(sheet => sheet.getAttribute('r:id'));
|
||||
|
||||
// Read the relations to get the actual filenames for each sheet
|
||||
const workbookRelsXml = await entries['xl/_rels/workbook.xml.rels'].text();
|
||||
const workbookRelsEntry = entryByFilename.get('xl/_rels/workbook.xml.rels')
|
||||
|
||||
if(!workbookRelsEntry){
|
||||
throw new TypeError(`entry 'xl/_rels/workbook.xml.rels' manquante dans le zip`)
|
||||
}
|
||||
|
||||
//@ts-ignore
|
||||
const workbookRelsXml = await workbookRelsEntry.getData(new TextWriter());
|
||||
const workbookRelsDoc = parseXML(workbookRelsXml);
|
||||
const sheetRels = Array.from(workbookRelsDoc.getElementsByTagName('Relationship'));
|
||||
const sheetFiles = sheetIds.map(id => sheetRels.find(rel => rel.getAttribute('Id') === id).getAttribute('Target').replace('worksheets/', ''));
|
||||
|
||||
// Read each sheet's XML and extract data in parallel
|
||||
const sheetDataPs = sheetFiles.map((sheetFile, index) => (
|
||||
entries[`xl/worksheets/${sheetFile}`].text().then(sheetXml => {
|
||||
// @ts-ignore
|
||||
entryByFilename.get(`xl/worksheets/${sheetFile}`).getData(new TextWriter()).then(sheetXml => {
|
||||
const sheetDoc = parseXML(sheetXml);
|
||||
|
||||
const rows = sheetDoc.getElementsByTagName('sheetData')[0].getElementsByTagName('row');
|
||||
|
||||
@ -2,7 +2,10 @@ import test from 'ava';
|
||||
|
||||
import {getODSTableRawContent, createOdsFile} from '../scripts/node.js'
|
||||
|
||||
/** @import {SheetName, SheetRawContent} from '../scripts/types.js' */
|
||||
|
||||
test('basic file creation', async t => {
|
||||
/** @type {Map<SheetName, SheetRawContent>} */
|
||||
const content = new Map([
|
||||
[
|
||||
'La feuille',
|
||||
@ -15,7 +18,7 @@ test('basic file creation', async t => {
|
||||
]
|
||||
])
|
||||
|
||||
// @ts-ignore
|
||||
|
||||
const odsFile = await createOdsFile(content)
|
||||
|
||||
const parsedContent = await getODSTableRawContent(odsFile)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user