3867 lines
794 KiB
HTML
3867 lines
794 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html lang="en">
|
||
|
<head>
|
||
|
<meta charset="utf-8" />
|
||
|
<title>SheetJS Community Edition</title>
|
||
|
<link rel="icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAKCgr/FRUX/xYWGP8YGBr/GRkb/xsbHP8dHR7/Hh4f/x4eIP8fHyD/ICAh/yMjJP8kJCX/JiYo/ygoKv8pKSr/LCwu/y0tLv80NDT/QUFC/0ZGR/9MTE7/UFBR/1JSUv9bW1v/XFxc/2BgYP9hYWP/aGhp/2xsbP9ycnL/d3d3/3l5e/98fHz/f3+A/2dn/P9z3a//cNX8/4CAgP+Xl5f/nZ2e/56en/+fn5//n5+h/6amp/+rq6v/rKys/7CvsP+zs7T/uLi5/7u7u/+8vLz/wMDA/8fHx//Kysr/zc3N/9HR0f/d3d3/3t7e/+Xl5f/q6ur/6+vr/+3t7f/z8/P/9fX1//b29v/39/f/+Pj4//n5+f/6+vr/+/v7//z8/P/9/f3//v7+//////8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/NCYmJiYmJiYmJiYmJiYmNCZKSkpKSkpKSkpKSkpKSiYmSkpKRisdRkMbMklKSkomJkpKSSEiNUhEEQwpSUpKJiZKSi8LHhhAPAwBDDZKSiYmSkoWACA7SEc6HAEaSkomJkpKBxI/SkpKSj4ICkpKJiZKSgUTR0pKSkpGDwZKSiYmSkoTED1KSkpKOQQVSkomJkpKKgowMy4sNycIMUpKJiZKSkEZDgkDAgsNH0VKSiYmSkpKQigUBgkXLUhKSkomJkpKSkpKSkpKSkpKSkpKJiYmJiYmJiYmJiYmJiYmJiYmIyUkNDQ0NDQ0NDQ0NDQmOCYmJiYmJiYmJiYmJiYmOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" />
|
||
|
<link rel="stylesheet" href="/__/grip/static/octicons/octicons.css" />
|
||
|
<style>
|
||
|
/*!
|
||
|
* GitHub Light v0.4.1
|
||
|
* Copyright (c) 2012 - 2017 GitHub, Inc.
|
||
|
* Licensed under MIT (https://github.com/primer/github-syntax-theme-generator/blob/master/LICENSE)
|
||
|
*/.pl-c{color:#6a737d}.pl-c1,.pl-s .pl-v{color:#005cc5}.pl-e,.pl-en{color:#6f42c1}.pl-smi,.pl-s .pl-s1{color:#24292e}.pl-ent{color:#22863a}.pl-k{color:#d73a49}.pl-s,.pl-pds,.pl-s .pl-pse .pl-s1,.pl-sr,.pl-sr .pl-cce,.pl-sr .pl-sre,.pl-sr .pl-sra{color:#032f62}.pl-v,.pl-smw{color:#e36209}.pl-bu{color:#b31d28}.pl-ii{color:#fafbfc;background-color:#b31d28}.pl-c2{color:#fafbfc;background-color:#d73a49}.pl-c2::before{content:"^M"}.pl-sr .pl-cce{font-weight:bold;color:#22863a}.pl-ml{color:#735c0f}.pl-mh,.pl-mh .pl-en,.pl-ms{font-weight:bold;color:#005cc5}.pl-mi{font-style:italic;color:#24292e}.pl-mb{font-weight:bold;color:#24292e}.pl-md{color:#b31d28;background-color:#ffeef0}.pl-mi1{color:#22863a;background-color:#f0fff4}.pl-mc{color:#e36209;background-color:#ffebda}.pl-mi2{color:#f6f8fa;background-color:#005cc5}.pl-mdr{font-weight:bold;color:#6f42c1}.pl-ba{color:#586069}.pl-sg{color:#959da5}.pl-corl{text-decoration:underline;color:#032f62}.CodeMirror{font-family:monospace;height:300px;color:black;direction:ltr}.CodeMirror-lines{padding:4px 0}.CodeMirror pre{padding:0 4px}.CodeMirror-scrollbar-filler,.CodeMirror-gutter-filler{background-color:white}.CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;white-space:nowrap}.CodeMirror-guttermarker{color:black}.CodeMirror-guttermarker-subtle{color:#999}.CodeMirror-cursor{border-left:1px solid black;border-right:none;width:0}.CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.cm-fat-cursor .CodeMirror-cursor{width:auto;border:0 !important;background:#7e7}.cm-fat-cursor div.CodeMirror-cursors{z-index:1}.cm-fat-cursor-mark{background-color:rgba(20,255,20,0.5);animation:blink 1.06s steps(1) infinite}.cm-animate-fat-cursor{width:auto;border:0;animation:blink 1.06s steps(1) infinite;background-color:#7e7}@keyframes blink{0%{}50%{background-color:transparent}100%{}}.cm-tab{display:inline-block;text-decoration:inherit}.CodeMirror-rulers{position:absolute;left:0;right:0;top:-50px;bottom:-20px;overflow:hidden}.CodeMirror-ruler{border-left:1px solid #ccc;top:0;bottom:0;position:absolute}.cm-s-default .cm-header{color:blue}.cm-s-default .cm-quote{color:#090}.cm-negative{color:#d44}.cm-positive{color:#292}.cm-header,.cm-strong{font-weight:bold}.cm-em{font-style:italic}.cm-link{text-decoration:underline}.cm-strikethrough{text-decoration:line-through}.cm-s-default .cm-keyword{color:#708}.cm-s-default .cm-atom{color:#219}.cm-s-default .cm-number{color:#164}.cm-s-default .cm-def{color:#00f}.cm-s-default .cm-variable-2{color:#05a}.cm-s-default .cm-variable-3,.cm-s-default .cm-type{color:#085}.cm-s-default .cm-comment{color:#a50}.cm-s-default .cm-string{color:#a11}.cm-s-default .cm-string-2{color:#f50}.cm-s-default .cm-meta{color:#555}.cm-s-default .cm-qualifier{color:#555}.cm-s-default .cm-builtin{color:#30a}.cm-s-default .cm-bracket{color:#997}.cm-s-default .cm-tag{color:#170}.cm-s-default .cm-attribute{color:#00c}.cm-s-default .cm-hr{color:#999}.cm-s-default .cm-link{color:#00c}.cm-s-default .cm-error{color:#f00}.cm-invalidchar{color:#f00}.CodeMirror-composing{border-bottom:2px solid}div.CodeMirror span.CodeMirror-matchingbracket{color:#0b0}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#a22}.CodeMirror-matchingtag{background:rgba(255,150,0,0.3)}.CodeMirror-activeline-background{background:#e8f2ff}.CodeMirror{position:relative;overflow:hidden;background:white}.CodeMirror-scroll{overflow:scroll !important;margin-bottom:-30px;margin-right:-30px;padding-bottom:30px;height:100%;outline:none;position:relative}.CodeMirror-sizer{position:relative;border-right:30px solid transparent}.CodeMirror-vscrollbar,.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-gutter-filler{position:absolute;z-index:6;display:none}.CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.CodeMirror-scrollbar-filler{right:0;bottom:0}.CodeMirror-gutter-filler{left:0;bottom
|
||
|
* GitHub Light v0.4.2
|
||
|
* Copyright (c) 2012 - 2017 GitHub, Inc.
|
||
|
* Licensed under MIT (https://github.com/primer/github-syntax-theme-generator/blob/master/LICENSE)
|
||
|
*/.cm-s-github-light.CodeMirror{background:#fff;color:#24292e}.cm-s-github-light .CodeMirror-gutters{background:#fff;border-right-width:0}.cm-s-github-light .CodeMirror-guttermarker{color:white}.cm-s-github-light .CodeMirror-guttermarker-subtle{color:#d0d0d0}.cm-s-github-light .CodeMirror-linenumber{color:#959da5;padding:0 16px 0 16px}.cm-s-github-light .CodeMirror-cursor{border-left:1px solid #24292e}.cm-s-github-light div.CodeMirror-selected,.cm-s-github-light .CodeMirror-line::-moz-selection,.cm-s-github-light .CodeMirror-line>span::-moz-selection,.cm-s-github-light .CodeMirror-line>span>span::-moz-selection,.cm-s-github-light .CodeMirror-line::-moz-selection,.cm-s-github-light .CodeMirror-line>span::-moz-selection,.cm-s-github-light .CodeMirror-line>span>span::-moz-selection{background:#c8c8fa}.cm-s-github-light div.CodeMirror-selected,.cm-s-github-light .CodeMirror-line::selection,.cm-s-github-light .CodeMirror-line>span::selection,.cm-s-github-light .CodeMirror-line>span>span::selection,.cm-s-github-light .CodeMirror-line::-moz-selection,.cm-s-github-light .CodeMirror-line>span::-moz-selection,.cm-s-github-light .CodeMirror-line>span>span::-moz-selection{background:#c8c8fa}.cm-s-github-light .CodeMirror-activeline-background{background:#fafbfc}.cm-s-github-light .CodeMirror-matchingbracket{text-decoration:underline;color:#24292e !important}.cm-s-github-light .CodeMirror-lines{font-family:"SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size:12px;background:#fff;line-height:1.5}.cm-s-github-light .cm-comment{color:#6a737d}.cm-s-github-light .cm-constant{color:#005cc5}.cm-s-github-light .cm-entity{font-weight:normal;font-style:normal;text-decoration:none;color:#6f42c1}.cm-s-github-light .cm-keyword{font-weight:normal;font-style:normal;text-decoration:none;color:#d73a49}.cm-s-github-light .cm-storage{color:#d73a49}.cm-s-github-light .cm-string{font-weight:normal;font-style:normal;text-decoration:none;color:#032f62}.cm-s-github-light .cm-support{font-weight:normal;font-style:normal;text-decoration:none;color:#005cc5}.cm-s-github-light .cm-variable{font-weight:normal;font-style:normal;text-decoration:none;color:#e36209}details-dialog{position:fixed;margin:10vh auto;top:0;left:50%;transform:translateX(-50%);z-index:999;max-height:80vh;max-width:90vw;width:448px}.octicon{display:inline-block;vertical-align:text-top;fill:currentColor}body.intent-mouse [role="button"]:focus,body.intent-mouse button:focus,body.intent-mouse summary:focus{outline:none}.CodeMirror{height:calc(100vh - 1px)}.file-editor-textarea{width:100%;padding:5px 4px;font:12px "SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;resize:vertical;border:0;border-radius:0;outline:none}.container-preview .tabnav-tabs{margin:-6px 0 -6px -11px}.container-preview .tabnav-tabs .tabnav-tab{padding:12px 15px;border-radius:0}.container-preview .tabnav-tabs>.selected:first-child{border-top-left-radius:3px}.container-preview .tabnav-tabs .selected{font-weight:600}.container-preview.template-editor .commit-create,.container-preview.template-editor .file-actions{display:block}.container-preview.template-editor .show-code,.container-preview.template-editor .commit-preview,.container-preview.template-editor .loading-preview-msg,.container-preview.template-editor .no-changes-preview-msg,.container-preview.template-editor .error-preview-msg{display:none}.container-preview.render-editor .commit-create,.container-preview.render-editor .file-actions{display:block}.container-preview.render-editor .template-editor,.container-preview.render-editor .show-code,.container-preview.render-editor .commit-preview,.container-preview.render-editor .loading-preview-msg,.container-preview.render-editor .no-changes-preview-msg,.container-preview.render-editor .error-preview-msg{display:none}.container-preview.show-code .commit-create,.container-preview.show-code .file-actions{display:block}.container-preview.show-code .template-editor,.container-preview.show-code .render-editor,.container-preview.show-code .commit-preview,.container-preview.show-cod
|
||
|
* Primer-core
|
||
|
* http://primer.github.io
|
||
|
*
|
||
|
* Released under MIT license. Copyright (c) 2018 GitHub Inc.
|
||
|
*//*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section{display:block}summary{display:list-item}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}template,[hidden]{display:none}a{background-color:transparent}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}button,input,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}button,input{overflow:visible}button,select{text-transform:none}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-input-placeholder{color:inherit;opacity:0.54}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}*{box-sizing:border-box}input,select,textarea,button{font-family:inherit;font-size:inherit;line-height:inherit}body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:14px;line-height:1.5;color:#24292e;background-color:#fff}a{color:#0366d6;text-decoration:none}a:hover{text-decoration:underline}b,strong{font-weight:600}hr,.rule{height:0;margin:15px 0;overflow:hidden;background:transparent;border:0;border-bottom:1px solid #dfe2e5}hr::before,.rule::before{display:table;content:""}hr::after,.rule::after{display:table;clear:both;content:""}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}button{cursor:pointer;border-radius:0}details summary{cursor:pointer}details:not([open])>*:not(summary){display:none !important}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:0}h1{font-size:32px;font-weight:600}h2{font-size:24px;font-weight:600}h3{font-size:20px;font-weight:600}h4{font-size:16px;font-weight:600}h5{font-size:14px;font-weight:600}h6{font-size:12px;font-weight:600}p{margin-top:0;margin-bottom:10px}small{font-size:90%}blockquote{margin:0}ul,ol{padding-left:0;margin-top:0;margin-bottom:0}ol ol,ul ol{list-style-type:lower-roman}ul ul ol,ul ol ol,ol ul ol,ol ol ol{list-style-type:lower-alpha}dd{margin-left:0}tt,code{font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px}pre{margin-top:0;margin-bottom:0;font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px}.octicon{vertical-align:text-bottom}.Box{background-color:#fff;border:1px solid #d1d5da;border-radius:3px}.Box--condensed{line-height:1.25}.Box--condensed .Box-header{padding:8px 16px}.Box--condensed .Box-body{padding:8px 16px}.B
|
||
|
/*# sourceMappingURL=frameworks-afd119c67567f2c750f08c93d4211333.css.map */
|
||
|
|
||
|
/*!
|
||
|
* Primer-marketing
|
||
|
* http://primer.github.io
|
||
|
*
|
||
|
* Released under MIT license. Copyright (c) 2018 GitHub Inc.
|
||
|
*/.alt-mono-font{font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace}.alt-h0,.alt-h1,.alt-h2,.alt-h3,.alt-h4,.alt-h5,.alt-h6,.alt-lead{-webkit-font-smoothing:antialiased;font-family:Roboto,-apple-system,BlinkMacSystemFont,"Helvetica Neue","Segoe UI","Oxygen","Ubuntu","Cantarell","Open Sans",sans-serif}.alt-h0{font-size:48px;font-weight:300}@media (min-width: 768px){.alt-h0{font-size:54px}}@media (min-width: 1012px){.alt-h0{font-size:72px}}.alt-h1{font-size:36px;font-weight:300}@media (min-width: 768px){.alt-h1{font-size:48px}}@media (min-width: 1012px){.alt-h1{font-size:54px}}.alt-h2{font-size:28px;font-weight:300}@media (min-width: 768px){.alt-h2{font-size:34px}}@media (min-width: 1012px){.alt-h2{font-size:38px}}.alt-h3{font-size:18px;font-weight:400}@media (min-width: 768px){.alt-h3{font-size:20px}}@media (min-width: 1012px){.alt-h3{font-size:22px}}.alt-h4{font-size:16px;font-weight:500}.alt-h5{font-size:14px;font-weight:500}.alt-h6{font-size:12px;font-weight:500}.alt-lead{-webkit-font-smoothing:antialiased;font-size:21px;font-weight:300}@media (min-width: 768px){.alt-lead{font-size:24px}}@media (min-width: 1012px){.alt-lead{font-size:26px}}.alt-text-small{font-size:14px !important}.pullquote{padding-top:0;padding-bottom:0;padding-left:8px;margin-bottom:24px;font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:16px;line-height:1.4;color:#586069;border-left:3px solid #e1e4e8}@media (min-width: 768px){.pullquote{padding-left:12px;margin-bottom:32px;margin-left:-15px;font-size:18px;line-height:1.5}}.btn-orange{color:#fff;background-color:#d25a08;background-image:linear-gradient(-180deg, #f7802f 0%, #d25a08 90%)}.btn-orange:focus,.btn-orange.focus{box-shadow:0 0 0 0.2em rgba(247,128,47,0.4)}.btn-orange:hover,.btn-orange.hover{background-color:#c85607;background-image:linear-gradient(-180deg, #f77a25 0%, #c85607 90%);background-position:-.5em;border-color:rgba(27,31,35,0.5)}.btn-orange:active,.btn-orange.selected,[open]>.btn-orange{background-color:#c65e17;background-image:none;border-color:rgba(27,31,35,0.5);box-shadow:inset 0 0.15em 0.3em rgba(27,31,35,0.15)}.btn-orange:disabled,.btn-orange.disabled{color:rgba(255,255,255,0.75);background-color:#e9ad83;background-image:none;border-color:rgba(27,31,35,0.2);box-shadow:none}.btn-orange .Counter{color:#f46909;background-color:#fff}.btn-outline-purple{color:#6f42c1;background-color:#fff;background-image:none}.btn-outline-purple .Counter{background-color:rgba(27,31,35,0.07)}.btn-outline-purple:hover,.btn-outline-purple:active,.btn-outline-purple.selected,[open]>.btn-outline-purple{color:#fff;background-color:#6f42c1;background-image:none;border-color:#6f42c1}.btn-outline-purple:hover .Counter,.btn-outline-purple:active .Counter,.btn-outline-purple.selected .Counter,[open]>.btn-outline-purple .Counter{color:#6f42c1;background-color:#fff}.btn-outline-purple:focus{border-color:#6f42c1;box-shadow:0 0 0 0.2em rgba(111,66,193,0.4)}.btn-outline-purple:disabled,.btn-outline-purple.disabled{color:rgba(27,31,35,0.3);background-color:#fff;border-color:rgba(27,31,35,0.15);box-shadow:none}.btn-outline-orange{color:#f66a0a;background-color:#fff;background-image:none}.btn-outline-orange .Counter{background-color:rgba(27,31,35,0.07)}.btn-outline-orange:hover,.btn-outline-orange:active,.btn-outline-orange.selected,[open]>.btn-outline-orange{color:#fff;background-color:#f66a0a;background-image:none;border-color:#f66a0a}.btn-outline-orange:hover .Counter,.btn-outline-orange:active .Counter,.btn-outline-orange.selected .Counter,[open]>.btn-outline-orange .Counter{color:#f66a0a;background-color:#fff}.btn-outline-orange:focus{border-color:#f66a0a;box-shadow:0 0 0 0.2em rgba(246,106,10,0.4)}.btn-outline-orange:disabled,.btn-outline-orange.disabled{color:rgba(27,31,35,0.3);background-color:#fff;border-color:rgba(27,31,35,0.15);box-shadow:none}.btn-outline-green{color:#28a745;background-color:#fff;background-image:none}.btn-outline-green .Counter{background-color:rgba(27,31,35,0.07)}.btn-outline-green:hover,.btn-outline-green:active,.bt
|
||
|
/*# sourceMappingURL=site-73680c8bae9d90e48e18affb463ea2cd.css.map */
|
||
|
|
||
|
/*!
|
||
|
* Primer-product
|
||
|
* http://primer.github.io
|
||
|
*
|
||
|
* Released under MIT license. Copyright (c) 2018 GitHub Inc.
|
||
|
*/.flash{position:relative;padding:16px;color:#032f62;background-color:#dbedff;border:1px solid rgba(27,31,35,0.15);border-radius:3px}.flash p:last-child{margin-bottom:0}.flash-messages{margin-bottom:24px}.flash-close{float:right;padding:16px;margin:-16px;color:inherit;text-align:center;cursor:pointer;background:none;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;opacity:0.6}.flash-close:hover{opacity:1}.flash-action{float:right;margin-top:-3px;margin-left:24px}.flash-warn{color:#735c0f;background-color:#fffbdd;border-color:rgba(27,31,35,0.15)}.flash-error{color:#86181d;background-color:#ffdce0;border-color:rgba(27,31,35,0.15)}.flash-success{color:#165c26;background-color:#dcffe4;border-color:rgba(27,31,35,0.15)}.flash-full{margin-top:-1px;border-width:1px 0;border-radius:0}.warning{padding:.5em;margin-bottom:0.8em;font-weight:600;background-color:#fffbdd}.avatar{display:inline-block;overflow:hidden;line-height:1;vertical-align:middle;border-radius:3px}.avatar-small{border-radius:2px}.avatar-link{float:left;line-height:1}.avatar-group-item{display:inline-block;margin-bottom:3px}.avatar-parent-child{position:relative}.avatar-child{position:absolute;right:-15%;bottom:-9%;background-color:#fff;border-radius:2px;box-shadow:-2px -2px 0 rgba(255,255,255,0.8)}.avatar-stack{display:inline-block;white-space:nowrap}.avatar-stack .avatar{position:relative;z-index:2;display:inline-block;width:20px;height:20px;box-sizing:content-box;margin-right:-15px;background-color:#fff;border-right:1px solid #fff;border-radius:2px;transition:margin 0.1s ease-in-out}.avatar-stack .avatar:only-child{background-color:transparent}.avatar-stack .avatar:first-child{z-index:3}.avatar-stack .avatar:last-child{z-index:1;margin-right:0;border-right:0}.avatar-stack:hover .avatar{margin-right:3px}.avatar-stack:hover .avatar:last-child{margin-right:0}.AvatarStack{position:relative;min-width:26px;height:20px}.AvatarStack .AvatarStack-body{position:absolute}.AvatarStack.AvatarStack--two{min-width:36px}.AvatarStack.AvatarStack--three-plus{min-width:46px}.AvatarStack-body{display:flex;background:#fff}.AvatarStack-body .avatar{position:relative;z-index:2;display:flex;width:20px;height:20px;box-sizing:content-box;margin-right:-11px;background-color:#fff;border-right:1px solid #fff;border-radius:2px;transition:margin 0.1s ease-in-out}.AvatarStack-body .avatar:first-child{z-index:3}.AvatarStack-body .avatar:last-child{z-index:1;border-right:0}.AvatarStack-body .avatar img{border-radius:2px}.AvatarStack-body .avatar:nth-child(n+4){display:none;opacity:0}.AvatarStack-body:hover .avatar{margin-right:3px}.AvatarStack-body:hover .avatar:nth-child(n+4){display:flex;opacity:1}.AvatarStack-body:hover .avatar-more{display:none !important}.avatar.avatar-more{z-index:1;margin-right:0;background:#f6f8fa}.avatar.avatar-more::before,.avatar.avatar-more::after{position:absolute;display:block;height:20px;content:"";border-radius:2px;outline:1px solid #fff}.avatar.avatar-more::before{width:17px;background:#e1e4e8}.avatar.avatar-more::after{width:14px;background:#d1d5da}.AvatarStack--right .AvatarStack-body{right:0;flex-direction:row-reverse}.AvatarStack--right .AvatarStack-body:hover .avatar{margin-right:0;margin-left:3px}.AvatarStack--right .avatar.avatar-more{background:#d1d5da}.AvatarStack--right .avatar.avatar-more::before{width:5px}.AvatarStack--right .avatar.avatar-more::after{width:2px;background:#f6f8fa}.AvatarStack--right .avatar{margin-right:0;margin-left:-11px;border-right:0;border-left:1px solid #fff}.CircleBadge{display:flex;align-items:center;justify-content:center;background-color:#fff;border-radius:50%;box-shadow:0 1px 5px rgba(27,31,35,0.15)}.CircleBadge-icon{max-width:60% !important;height:auto !important;max-height:55% !important}.CircleBadge--small{width:56px;height:56px}.CircleBadge--medium{width:96px;height:96px}.CircleBadge--large{width:128px;height:128px}.DashedConnection{position:relative}.DashedConnection::before{position:absolute;top:50%;left:0;width:100%;content:"";border-bottom:2px dashed #e1e4e8}.DashedConnection .CircleBadge{pos
|
||
|
/*# sourceMappingURL=github-a12fe4c88979a8931d7e7adfee5656fc.css.map */
|
||
|
|
||
|
</style>
|
||
|
<style>
|
||
|
/* Page tweaks */
|
||
|
.preview-page {
|
||
|
margin-top: 64px;
|
||
|
}
|
||
|
/* User-content tweaks */
|
||
|
.timeline-comment-wrapper > .timeline-comment:after,
|
||
|
.timeline-comment-wrapper > .timeline-comment:before {
|
||
|
content: none;
|
||
|
}
|
||
|
/* User-content overrides */
|
||
|
.discussion-timeline.wide {
|
||
|
width: 920px;
|
||
|
}
|
||
|
</style>
|
||
|
</head>
|
||
|
<body>
|
||
|
<div class="page">
|
||
|
<div id="preview-page" class="preview-page" data-autorefresh-url="">
|
||
|
|
||
|
|
||
|
|
||
|
<div role="main" class="main-content">
|
||
|
<div class="container new-discussion-timeline experiment-repo-nav">
|
||
|
<div class="repository-content">
|
||
|
<div id="readme" class="readme boxed-group clearfix announce instapaper_body md">
|
||
|
|
||
|
<h3>
|
||
|
<span class="octicon octicon-book"></span>
|
||
|
SheetJS Community Edition
|
||
|
</h3>
|
||
|
|
||
|
<article class="markdown-body entry-content" itemprop="text" id="grip-content">
|
||
|
<h1>
|
||
|
<a id="user-content-sheetjs-js-xlsx" class="anchor" href="#sheetjs-js-xlsx" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a><a href="http://sheetjs.com" rel="nofollow">SheetJS js-xlsx</a>
|
||
|
</h1>
|
||
|
<p>Parser and writer for various spreadsheet formats. Pure-JS cleanroom
|
||
|
implementation from official specifications, related documents, and test files.
|
||
|
Emphasis on parsing and writing robustness, cross-format feature compatibility
|
||
|
with a unified JS representation, and ES3/ES5 browser compatibility back to IE6.</p>
|
||
|
<p>This is the community version. We also offer a pro version with performance
|
||
|
enhancements, additional features like styling, and dedicated support.</p>
|
||
|
<p><a href="http://sheetjs.com/pro" rel="nofollow"><strong>Pro Version</strong></a></p>
|
||
|
<p><a href="http://sheetjs.com/support" rel="nofollow"><strong>Commercial Support</strong></a></p>
|
||
|
<p><a href="http://docs.sheetjs.com/" rel="nofollow"><strong>Rendered Documentation</strong></a></p>
|
||
|
<p><a href="http://sheetjs.com/demos" rel="nofollow"><strong>In-Browser Demos</strong></a></p>
|
||
|
<p><a href="http://git.io/xlsx" rel="nofollow"><strong>Source Code</strong></a></p>
|
||
|
<p><a href="https://github.com/sheetjs/sheetjs/issues"><strong>Issues and Bug Reports</strong></a></p>
|
||
|
<p><a href="#file-formats"><strong>File format support for known spreadsheet data formats:</strong></a></p>
|
||
|
<details>
|
||
|
<summary><b>Graph of supported formats</b> (click to show)</summary>
|
||
|
<p><a href="formats.png" target="_blank" rel="noopener noreferrer"><img src="formats.png" alt="circo graph of format support" style="max-width:100%;"></a></p>
|
||
|
<p><a href="legend.png" target="_blank" rel="noopener noreferrer"><img src="legend.png" alt="graph legend" style="max-width:100%;"></a></p>
|
||
|
</details>
|
||
|
<p><a href="http://oss.sheetjs.com/sheetjs/tests/" rel="nofollow"><strong>Browser Test</strong></a></p>
|
||
|
<p><a href="https://saucelabs.com/u/sheetjs" rel="nofollow"><img src="https://camo.githubusercontent.com/fd1391703fe12774261a10e488d70e69221d00fc/68747470733a2f2f73617563656c6162732e636f6d2f62726f777365722d6d61747269782f73686565746a732e737667" alt="Build Status" data-canonical-src="https://saucelabs.com/browser-matrix/sheetjs.svg" style="max-width:100%;"></a></p>
|
||
|
<p><a href="https://travis-ci.org/SheetJS/sheetjs" rel="nofollow"><img src="https://camo.githubusercontent.com/468eb8bd829c0ba0c6f406ee527012fc0dd73359/68747470733a2f2f7472617669732d63692e6f72672f53686565744a532f73686565746a732e7376673f6272616e63683d6d6173746572" alt="Build Status" data-canonical-src="https://travis-ci.org/SheetJS/sheetjs.svg?branch=master" style="max-width:100%;"></a>
|
||
|
<a href="https://semaphoreci.com/sheetjs/sheetjs" rel="nofollow"><img src="https://camo.githubusercontent.com/d9847fd0a63745690571fc100998550693dc9028/68747470733a2f2f73656d6170686f726563692e636f6d2f6170692f76312f73686565746a732f73686565746a732f6272616e636865732f6d61737465722f736869656c64735f62616467652e737667" alt="Build Status" data-canonical-src="https://semaphoreci.com/api/v1/sheetjs/sheetjs/branches/master/shields_badge.svg" style="max-width:100%;"></a>
|
||
|
<a href="https://coveralls.io/r/SheetJS/sheetjs?branch=master" rel="nofollow"><img src="https://camo.githubusercontent.com/689643ec359f193937606820197ad22d9b822680/687474703a2f2f696d672e736869656c64732e696f2f636f766572616c6c732f53686565744a532f73686565746a732f6d61737465722e737667" alt="Coverage Status" data-canonical-src="http://img.shields.io/coveralls/SheetJS/sheetjs/master.svg" style="max-width:100%;"></a>
|
||
|
<a href="https://david-dm.org/sheetjs/sheetjs" rel="nofollow"><img src="https://camo.githubusercontent.com/5ad03f0baa0cd1b53e28141c3b575aa670f6a5bf/68747470733a2f2f64617669642d646d2e6f72672f73686565746a732f73686565746a732f7374617475732e737667" alt="Dependencies Status" data-canonical-src="https://david-dm.org/sheetjs/sheetjs/status.svg" style="max-width:100%;"></a>
|
||
|
<a href="https://npmjs.org/package/xlsx" rel="nofollow"><img src="https://camo.githubusercontent.com/ef6cc5f87176e5228dfd551d206d55277d951c4b/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f64742f786c73782e737667" alt="npm Downloads" data-canonical-src="https://img.shields.io/npm/dt/xlsx.svg" style="max-width:100%;"></a>
|
||
|
<a href="https://github.com/SheetJS/sheetjs"><img src="https://camo.githubusercontent.com/808e156528624950a96ff4714554d8fcb962a8cc/68747470733a2f2f67612d626561636f6e2e61707073706f742e636f6d2f55412d33363831303333332d312f53686565744a532f73686565746a733f706978656c" alt="Analytics" data-canonical-src="https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/sheetjs?pixel" style="max-width:100%;"></a></p>
|
||
|
<h2>
|
||
|
<a id="user-content-table-of-contents" class="anchor" href="#table-of-contents" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Table of Contents</h2>
|
||
|
<details>
|
||
|
<summary><b>Expand to show Table of Contents</b></summary>
|
||
|
|
||
|
<ul>
|
||
|
<li>
|
||
|
<a href="#installation">Installation</a>
|
||
|
<ul>
|
||
|
<li><a href="#js-ecosystem-demos">JS Ecosystem Demos</a></li>
|
||
|
<li><a href="#optional-modules">Optional Modules</a></li>
|
||
|
<li><a href="#ecmascript-5-compatibility">ECMAScript 5 Compatibility</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li><a href="#philosophy">Philosophy</a></li>
|
||
|
<li>
|
||
|
<a href="#parsing-workbooks">Parsing Workbooks</a>
|
||
|
<ul>
|
||
|
<li><a href="#parsing-examples">Parsing Examples</a></li>
|
||
|
<li><a href="#streaming-read">Streaming Read</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#working-with-the-workbook">Working with the Workbook</a>
|
||
|
<ul>
|
||
|
<li><a href="#parsing-and-writing-examples">Parsing and Writing Examples</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#writing-workbooks">Writing Workbooks</a>
|
||
|
<ul>
|
||
|
<li><a href="#writing-examples">Writing Examples</a></li>
|
||
|
<li><a href="#streaming-write">Streaming Write</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#interface">Interface</a>
|
||
|
<ul>
|
||
|
<li><a href="#parsing-functions">Parsing functions</a></li>
|
||
|
<li><a href="#writing-functions">Writing functions</a></li>
|
||
|
<li><a href="#utilities">Utilities</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#common-spreadsheet-format">Common Spreadsheet Format</a>
|
||
|
<ul>
|
||
|
<li><a href="#general-structures">General Structures</a></li>
|
||
|
<li>
|
||
|
<a href="#cell-object">Cell Object</a>
|
||
|
<ul>
|
||
|
<li><a href="#data-types">Data Types</a></li>
|
||
|
<li><a href="#dates">Dates</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#sheet-objects">Sheet Objects</a>
|
||
|
<ul>
|
||
|
<li><a href="#worksheet-object">Worksheet Object</a></li>
|
||
|
<li><a href="#chartsheet-object">Chartsheet Object</a></li>
|
||
|
<li><a href="#macrosheet-object">Macrosheet Object</a></li>
|
||
|
<li><a href="#dialogsheet-object">Dialogsheet Object</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#workbook-object">Workbook Object</a>
|
||
|
<ul>
|
||
|
<li><a href="#workbook-file-properties">Workbook File Properties</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#workbook-level-attributes">Workbook-Level Attributes</a>
|
||
|
<ul>
|
||
|
<li><a href="#defined-names">Defined Names</a></li>
|
||
|
<li><a href="#workbook-views">Workbook Views</a></li>
|
||
|
<li><a href="#miscellaneous-workbook-properties">Miscellaneous Workbook Properties</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#document-features">Document Features</a>
|
||
|
<ul>
|
||
|
<li><a href="#formulae">Formulae</a></li>
|
||
|
<li><a href="#column-properties">Column Properties</a></li>
|
||
|
<li><a href="#row-properties">Row Properties</a></li>
|
||
|
<li><a href="#number-formats">Number Formats</a></li>
|
||
|
<li><a href="#hyperlinks">Hyperlinks</a></li>
|
||
|
<li><a href="#cell-comments">Cell Comments</a></li>
|
||
|
<li><a href="#sheet-visibility">Sheet Visibility</a></li>
|
||
|
<li><a href="#vba-and-macros">VBA and Macros</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#parsing-options">Parsing Options</a>
|
||
|
<ul>
|
||
|
<li><a href="#input-type">Input Type</a></li>
|
||
|
<li><a href="#guessing-file-type">Guessing File Type</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#writing-options">Writing Options</a>
|
||
|
<ul>
|
||
|
<li><a href="#supported-output-formats">Supported Output Formats</a></li>
|
||
|
<li><a href="#output-type">Output Type</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#utility-functions">Utility Functions</a>
|
||
|
<ul>
|
||
|
<li><a href="#array-of-arrays-input">Array of Arrays Input</a></li>
|
||
|
<li><a href="#array-of-objects-input">Array of Objects Input</a></li>
|
||
|
<li><a href="#html-table-input">HTML Table Input</a></li>
|
||
|
<li><a href="#formulae-output">Formulae Output</a></li>
|
||
|
<li>
|
||
|
<a href="#delimiter-separated-output">Delimiter-Separated Output</a>
|
||
|
<ul>
|
||
|
<li><a href="#utf-16-unicode-text">UTF-16 Unicode Text</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li><a href="#html-output">HTML Output</a></li>
|
||
|
<li><a href="#json">JSON</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#file-formats">File Formats</a>
|
||
|
<ul>
|
||
|
<li><a href="#excel-2007-xml-xlsxxlsm">Excel 2007+ XML (XLSX/XLSM)</a></li>
|
||
|
<li><a href="#excel-20-95-biff2biff3biff4biff5">Excel 2.0-95 (BIFF2/BIFF3/BIFF4/BIFF5)</a></li>
|
||
|
<li><a href="#excel-97-2004-binary-biff8">Excel 97-2004 Binary (BIFF8)</a></li>
|
||
|
<li><a href="#excel-2003-2004-spreadsheetml">Excel 2003-2004 (SpreadsheetML)</a></li>
|
||
|
<li><a href="#excel-2007-binary-xlsb-biff12">Excel 2007+ Binary (XLSB, BIFF12)</a></li>
|
||
|
<li><a href="#delimiter-separated-values-csvtxt">Delimiter-Separated Values (CSV/TXT)</a></li>
|
||
|
<li>
|
||
|
<a href="#other-workbook-formats">Other Workbook Formats</a>
|
||
|
<ul>
|
||
|
<li><a href="#lotus-1-2-3-wkswk1wk2wk3wk4123">Lotus 1-2-3 (WKS/WK1/WK2/WK3/WK4/123)</a></li>
|
||
|
<li><a href="#quattro-pro-wq1wq2wb1wb2wb3qpw">Quattro Pro (WQ1/WQ2/WB1/WB2/WB3/QPW)</a></li>
|
||
|
<li><a href="#opendocument-spreadsheet-odsfods">OpenDocument Spreadsheet (ODS/FODS)</a></li>
|
||
|
<li><a href="#uniform-office-spreadsheet-uos12">Uniform Office Spreadsheet (UOS1/2)</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#other-single-worksheet-formats">Other Single-Worksheet Formats</a>
|
||
|
<ul>
|
||
|
<li><a href="#dbase-and-visual-foxpro-dbf">dBASE and Visual FoxPro (DBF)</a></li>
|
||
|
<li><a href="#symbolic-link-sylk">Symbolic Link (SYLK)</a></li>
|
||
|
<li><a href="#lotus-formatted-text-prn">Lotus Formatted Text (PRN)</a></li>
|
||
|
<li><a href="#data-interchange-format-dif">Data Interchange Format (DIF)</a></li>
|
||
|
<li><a href="#html">HTML</a></li>
|
||
|
<li><a href="#rich-text-format-rtf">Rich Text Format (RTF)</a></li>
|
||
|
<li><a href="#ethercalc-record-format-eth">Ethercalc Record Format (ETH)</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#testing">Testing</a>
|
||
|
<ul>
|
||
|
<li><a href="#node">Node</a></li>
|
||
|
<li><a href="#browser">Browser</a></li>
|
||
|
<li><a href="#tested-environments">Tested Environments</a></li>
|
||
|
<li><a href="#test-files">Test Files</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#contributing">Contributing</a>
|
||
|
<ul>
|
||
|
<li><a href="#osxlinux">OSX/Linux</a></li>
|
||
|
<li><a href="#windows">Windows</a></li>
|
||
|
<li><a href="#tests">Tests</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li><a href="#license">License</a></li>
|
||
|
<li><a href="#references">References</a></li>
|
||
|
</ul>
|
||
|
|
||
|
</details>
|
||
|
<h2>
|
||
|
<a id="user-content-installation" class="anchor" href="#installation" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Installation</h2>
|
||
|
<p>In the browser, just add a script tag:</p>
|
||
|
<div class="highlight highlight-text-html-basic"><pre><<span class="pl-ent">script</span> <span class="pl-e">lang</span>=<span class="pl-s"><span class="pl-pds">"</span>javascript<span class="pl-pds">"</span></span> <span class="pl-e">src</span>=<span class="pl-s"><span class="pl-pds">"</span>dist/xlsx.full.min.js<span class="pl-pds">"</span></span>></<span class="pl-ent">script</span>></pre></div>
|
||
|
<details>
|
||
|
<summary><b>CDN Availability</b> (click to show)</summary>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="right">CDN</th>
|
||
|
<th align="left">URL</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="right"><code>unpkg</code></td>
|
||
|
<td align="left"><a href="https://unpkg.com/xlsx/" rel="nofollow">https://unpkg.com/xlsx/</a></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right"><code>jsDelivr</code></td>
|
||
|
<td align="left"><a href="https://jsdelivr.com/package/npm/xlsx" rel="nofollow">https://jsdelivr.com/package/npm/xlsx</a></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right"><code>CDNjs</code></td>
|
||
|
<td align="left"><a href="http://cdnjs.com/libraries/xlsx" rel="nofollow">http://cdnjs.com/libraries/xlsx</a></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right"><code>packd</code></td>
|
||
|
<td align="left"><a href="https://bundle.run/xlsx@latest?name=XLSX" rel="nofollow">https://bundle.run/xlsx@latest?name=XLSX</a></td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<p><code>unpkg</code> makes the latest version available at:</p>
|
||
|
<div class="highlight highlight-text-html-basic"><pre><<span class="pl-ent">script</span> <span class="pl-e">src</span>=<span class="pl-s"><span class="pl-pds">"</span>https://unpkg.com/xlsx/dist/xlsx.full.min.js<span class="pl-pds">"</span></span>></<span class="pl-ent">script</span>></pre></div>
|
||
|
</details>
|
||
|
<p>With <a href="https://www.npmjs.org/package/xlsx" rel="nofollow">npm</a>:</p>
|
||
|
<div class="highlight highlight-source-shell"><pre>$ npm install xlsx</pre></div>
|
||
|
<p>With <a href="http://bower.io/search/?q=js-xlsx" rel="nofollow">bower</a>:</p>
|
||
|
<div class="highlight highlight-source-shell"><pre>$ bower install js-xlsx</pre></div>
|
||
|
<h3>
|
||
|
<a id="user-content-js-ecosystem-demos" class="anchor" href="#js-ecosystem-demos" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>JS Ecosystem Demos</h3>
|
||
|
<p>The <a href="demos/"><code>demos</code> directory</a> includes sample projects for:</p>
|
||
|
<p><strong>Frameworks and APIs</strong></p>
|
||
|
<ul>
|
||
|
<li><a href="demos/angular/"><code>angularjs</code></a></li>
|
||
|
<li><a href="demos/angular2/"><code>angular 2 / 4 / 5 / 6 and ionic</code></a></li>
|
||
|
<li><a href="demos/knockout/"><code>knockout</code></a></li>
|
||
|
<li><a href="demos/meteor/"><code>meteor</code></a></li>
|
||
|
<li><a href="demos/react/"><code>react and react-native</code></a></li>
|
||
|
<li><a href="demos/vue/"><code>vue 2.x and weex</code></a></li>
|
||
|
<li><a href="demos/xhr/"><code>XMLHttpRequest and fetch</code></a></li>
|
||
|
<li><a href="demos/server/"><code>nodejs server</code></a></li>
|
||
|
<li><a href="demos/database/"><code>databases and key/value stores</code></a></li>
|
||
|
<li><a href="demos/array/"><code>typed arrays and math</code></a></li>
|
||
|
</ul>
|
||
|
<p><strong>Bundlers and Tooling</strong></p>
|
||
|
<ul>
|
||
|
<li><a href="demos/browserify/"><code>browserify</code></a></li>
|
||
|
<li><a href="demos/fusebox/"><code>fusebox</code></a></li>
|
||
|
<li><a href="demos/parcel/"><code>parcel</code></a></li>
|
||
|
<li><a href="demos/requirejs/"><code>requirejs</code></a></li>
|
||
|
<li><a href="demos/rollup/"><code>rollup</code></a></li>
|
||
|
<li><a href="demos/systemjs/"><code>systemjs</code></a></li>
|
||
|
<li><a href="demos/typescript/"><code>typescript</code></a></li>
|
||
|
<li><a href="demos/webpack/"><code>webpack 2.x</code></a></li>
|
||
|
</ul>
|
||
|
<p><strong>Platforms and Integrations</strong></p>
|
||
|
<ul>
|
||
|
<li><a href="demos/electron/"><code>electron application</code></a></li>
|
||
|
<li><a href="demos/nwjs/"><code>nw.js application</code></a></li>
|
||
|
<li><a href="demos/chrome/"><code>Chrome / Chromium extensions</code></a></li>
|
||
|
<li><a href="demos/extendscript/"><code>Adobe ExtendScript</code></a></li>
|
||
|
<li><a href="demos/headless/"><code>Headless Browsers</code></a></li>
|
||
|
<li><a href="demos/datagrid/"><code>canvas-datagrid</code></a></li>
|
||
|
<li><a href="demos/altjs/"><code>Swift JSC and other engines</code></a></li>
|
||
|
<li><a href="demos/function/"><code>"serverless" functions</code></a></li>
|
||
|
<li><a href="demos/oldie/"><code>internet explorer</code></a></li>
|
||
|
</ul>
|
||
|
<p>Other examples are included in the <a href="demos/showcase/">showcase</a>.</p>
|
||
|
<h3>
|
||
|
<a id="user-content-optional-modules" class="anchor" href="#optional-modules" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Optional Modules</h3>
|
||
|
<details>
|
||
|
<summary><b>Optional features</b> (click to show)</summary>
|
||
|
<p>The node version automatically requires modules for additional features. Some
|
||
|
of these modules are rather large in size and are only needed in special
|
||
|
circumstances, so they do not ship with the core. For browser use, they must
|
||
|
be included directly:</p>
|
||
|
<div class="highlight highlight-text-html-basic"><pre><span class="pl-c"><span class="pl-c"><!--</span> international support from js-codepage <span class="pl-c">--></span></span>
|
||
|
<<span class="pl-ent">script</span> <span class="pl-e">src</span>=<span class="pl-s"><span class="pl-pds">"</span>dist/cpexcel.js<span class="pl-pds">"</span></span>></<span class="pl-ent">script</span>></pre></div>
|
||
|
<p>An appropriate version for each dependency is included in the dist/ directory.</p>
|
||
|
<p>The complete single-file version is generated at <code>dist/xlsx.full.min.js</code></p>
|
||
|
<p>A slimmer build with XLSX / HTML support is generated at <code>dist/xlsx.mini.min.js</code></p>
|
||
|
<p>Webpack and Browserify builds include optional modules by default. Webpack can
|
||
|
be configured to remove support with <code>resolve.alias</code>:</p>
|
||
|
<div class="highlight highlight-source-js"><pre> <span class="pl-c"><span class="pl-c">/*</span> uncomment the lines below to remove support <span class="pl-c">*/</span></span>
|
||
|
resolve<span class="pl-k">:</span> {
|
||
|
alias<span class="pl-k">:</span> { <span class="pl-s"><span class="pl-pds">"</span>./dist/cpexcel.js<span class="pl-pds">"</span></span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span><span class="pl-pds">"</span></span> } <span class="pl-c"><span class="pl-c">//</span> <-- omit international support</span>
|
||
|
}</pre></div>
|
||
|
</details>
|
||
|
<h3>
|
||
|
<a id="user-content-ecmascript-5-compatibility" class="anchor" href="#ecmascript-5-compatibility" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>ECMAScript 5 Compatibility</h3>
|
||
|
<p>Since the library uses functions like <code>Array#forEach</code>, older browsers require
|
||
|
<a href="http://oss.sheetjs.com/js-xlsx/shim.js" rel="nofollow">shims to provide missing functions</a>.</p>
|
||
|
<p>To use the shim, add the shim before the script tag that loads <code>xlsx.js</code>:</p>
|
||
|
<div class="highlight highlight-text-html-basic"><pre><span class="pl-c"><span class="pl-c"><!--</span> add the shim first <span class="pl-c">--></span></span>
|
||
|
<<span class="pl-ent">script</span> <span class="pl-e">type</span>=<span class="pl-s"><span class="pl-pds">"</span>text/javascript<span class="pl-pds">"</span></span> <span class="pl-e">src</span>=<span class="pl-s"><span class="pl-pds">"</span>shim.min.js<span class="pl-pds">"</span></span>></<span class="pl-ent">script</span>>
|
||
|
<span class="pl-c"><span class="pl-c"><!--</span> after the shim is referenced, add the library <span class="pl-c">--></span></span>
|
||
|
<<span class="pl-ent">script</span> <span class="pl-e">type</span>=<span class="pl-s"><span class="pl-pds">"</span>text/javascript<span class="pl-pds">"</span></span> <span class="pl-e">src</span>=<span class="pl-s"><span class="pl-pds">"</span>xlsx.full.min.js<span class="pl-pds">"</span></span>></<span class="pl-ent">script</span>></pre></div>
|
||
|
<p>The script also includes <code>IE_LoadFile</code> and <code>IE_SaveFile</code> for loading and saving
|
||
|
files in Internet Explorer versions 6-9. The <code>xlsx.extendscript.js</code> script
|
||
|
bundles the shim in a format suitable for Photoshop and other Adobe products.</p>
|
||
|
<h2>
|
||
|
<a id="user-content-philosophy" class="anchor" href="#philosophy" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Philosophy</h2>
|
||
|
<details>
|
||
|
<summary><b>Philosophy</b> (click to show)</summary>
|
||
|
<p>Prior to SheetJS, APIs for processing spreadsheet files were format-specific.
|
||
|
Third-party libraries either supported one format, or they involved a separate
|
||
|
set of classes for each supported file type. Even though XLSB was introduced in
|
||
|
Excel 2007, nothing outside of SheetJS or Excel supported the format.</p>
|
||
|
<p>To promote a format-agnostic view, js-xlsx starts from a pure-JS representation
|
||
|
that we call the <a href="#common-spreadsheet-format">"Common Spreadsheet Format"</a>.
|
||
|
Emphasizing a uniform object representation enables new features like format
|
||
|
conversion (reading an XLSX template and saving as XLS) and circumvents the
|
||
|
"class trap". By abstracting the complexities of the various formats, tools
|
||
|
need not worry about the specific file type!</p>
|
||
|
<p>A simple object representation combined with careful coding practices enables
|
||
|
use cases in older browsers and in alternative environments like ExtendScript
|
||
|
and Web Workers. It is always tempting to use the latest and greatest features,
|
||
|
but they tend to require the latest versions of browsers, limiting usability.</p>
|
||
|
<p>Utility functions capture common use cases like generating JS objects or HTML.
|
||
|
Most simple operations should only require a few lines of code. More complex
|
||
|
operations generally should be straightforward to implement.</p>
|
||
|
<p>Excel pushes the XLSX format as default starting in Excel 2007. However, there
|
||
|
are other formats with more appealing properties. For example, the XLSB format
|
||
|
is spiritually similar to XLSX but files often tend up taking less than half the
|
||
|
space and open much faster! Even though an XLSX writer is available, other
|
||
|
format writers are available so users can take advantage of the unique
|
||
|
characteristics of each format.</p>
|
||
|
<p>The primary focus of the Community Edition is correct data interchange, focused
|
||
|
on extracting data from any compatible data representation and exporting data in
|
||
|
various formats suitable for any third party interface.</p>
|
||
|
</details>
|
||
|
<h2>
|
||
|
<a id="user-content-parsing-workbooks" class="anchor" href="#parsing-workbooks" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Parsing Workbooks</h2>
|
||
|
<p>For parsing, the first step is to read the file. This involves acquiring the
|
||
|
data and feeding it into the library. Here are a few common scenarios:</p>
|
||
|
<details>
|
||
|
<summary><b>nodejs read a file</b> (click to show)</summary>
|
||
|
<p><code>readFile</code> is only available in server environments. Browsers have no API for
|
||
|
reading arbitrary files given a path, so another strategy must be used.</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">if</span>(<span class="pl-k">typeof</span> require <span class="pl-k">!==</span> <span class="pl-s"><span class="pl-pds">'</span>undefined<span class="pl-pds">'</span></span>) <span class="pl-c1">XLSX</span> <span class="pl-k">=</span> <span class="pl-c1">require</span>(<span class="pl-s"><span class="pl-pds">'</span>xlsx<span class="pl-pds">'</span></span>);
|
||
|
<span class="pl-k">var</span> workbook <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-en">readFile</span>(<span class="pl-s"><span class="pl-pds">'</span>test.xlsx<span class="pl-pds">'</span></span>);
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> DO SOMETHING WITH workbook HERE <span class="pl-c">*/</span></span></pre></div>
|
||
|
</details>
|
||
|
<details>
|
||
|
<summary><b>Photoshop ExtendScript read a file</b> (click to show)</summary>
|
||
|
<p><code>readFile</code> wraps the <code>File</code> logic in Photoshop and other ExtendScript targets.
|
||
|
The specified path should be an absolute path:</p>
|
||
|
<div class="highlight highlight-source-js"><pre>#include <span class="pl-s"><span class="pl-pds">"</span>xlsx.extendscript.js<span class="pl-pds">"</span></span>
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> Read test.xlsx from the Documents folder <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-k">var</span> workbook <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-en">readFile</span>(<span class="pl-smi">Folder</span>.<span class="pl-smi">myDocuments</span> <span class="pl-k">+</span> <span class="pl-s"><span class="pl-pds">'</span>/<span class="pl-pds">'</span></span> <span class="pl-k">+</span> <span class="pl-s"><span class="pl-pds">'</span>test.xlsx<span class="pl-pds">'</span></span>);
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> DO SOMETHING WITH workbook HERE <span class="pl-c">*/</span></span></pre></div>
|
||
|
<p>The <a href="demos/extendscript/"><code>extendscript</code> demo</a> includes a more complex example.</p>
|
||
|
</details>
|
||
|
<details>
|
||
|
<summary><b>Browser read TABLE element from page</b> (click to show)</summary>
|
||
|
<p>The <code>table_to_book</code> and <code>table_to_sheet</code> utility functions take a DOM TABLE
|
||
|
element and iterate through the child nodes.</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> workbook <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">table_to_book</span>(<span class="pl-c1">document</span>.<span class="pl-c1">getElementById</span>(<span class="pl-s"><span class="pl-pds">'</span>tableau<span class="pl-pds">'</span></span>));
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> DO SOMETHING WITH workbook HERE <span class="pl-c">*/</span></span></pre></div>
|
||
|
<p>Multiple tables on a web page can be converted to individual worksheets:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">/*</span> create new workbook <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-k">var</span> workbook <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">book_new</span>();
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> convert table 'table1' to worksheet named "Sheet1" <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-k">var</span> ws1 <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">table_to_sheet</span>(<span class="pl-c1">document</span>.<span class="pl-c1">getElementById</span>(<span class="pl-s"><span class="pl-pds">'</span>table1<span class="pl-pds">'</span></span>));
|
||
|
<span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">book_append_sheet</span>(workbook, ws1, <span class="pl-s"><span class="pl-pds">"</span>Sheet1<span class="pl-pds">"</span></span>);
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> convert table 'table2' to worksheet named "Sheet2" <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-k">var</span> ws2 <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">table_to_sheet</span>(<span class="pl-c1">document</span>.<span class="pl-c1">getElementById</span>(<span class="pl-s"><span class="pl-pds">'</span>table2<span class="pl-pds">'</span></span>));
|
||
|
<span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">book_append_sheet</span>(workbook, ws2, <span class="pl-s"><span class="pl-pds">"</span>Sheet2<span class="pl-pds">"</span></span>);
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> workbook now has 2 worksheets <span class="pl-c">*/</span></span></pre></div>
|
||
|
<p>Alternatively, the HTML code can be extracted and parsed:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> htmlstr <span class="pl-k">=</span> <span class="pl-c1">document</span>.<span class="pl-c1">getElementById</span>(<span class="pl-s"><span class="pl-pds">'</span>tableau<span class="pl-pds">'</span></span>).<span class="pl-smi">outerHTML</span>;
|
||
|
<span class="pl-k">var</span> workbook <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-en">read</span>(htmlstr, {type<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">'</span>string<span class="pl-pds">'</span></span>});</pre></div>
|
||
|
</details>
|
||
|
<details>
|
||
|
<summary><b>Browser download file (ajax)</b> (click to show)</summary>
|
||
|
<p>Note: for a more complete example that works in older browsers, check the demo
|
||
|
at <a href="http://oss.sheetjs.com/js-xlsx/ajax.html" rel="nofollow">http://oss.sheetjs.com/js-xlsx/ajax.html</a>. The <a href="demos/xhr/"><code>xhr</code> demo</a>
|
||
|
includes more examples with <code>XMLHttpRequest</code> and <code>fetch</code>.</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> url <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">"</span>http://oss.sheetjs.com/test_files/formula_stress_test.xlsx<span class="pl-pds">"</span></span>;
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> set up async GET request <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-k">var</span> req <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-en">XMLHttpRequest</span>();
|
||
|
<span class="pl-smi">req</span>.<span class="pl-c1">open</span>(<span class="pl-s"><span class="pl-pds">"</span>GET<span class="pl-pds">"</span></span>, url, <span class="pl-c1">true</span>);
|
||
|
<span class="pl-smi">req</span>.<span class="pl-smi">responseType</span> <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">"</span>arraybuffer<span class="pl-pds">"</span></span>;
|
||
|
|
||
|
<span class="pl-smi">req</span>.<span class="pl-en">onload</span> <span class="pl-k">=</span> <span class="pl-k">function</span>(<span class="pl-smi">e</span>) {
|
||
|
<span class="pl-k">var</span> data <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-en">Uint8Array</span>(<span class="pl-smi">req</span>.<span class="pl-smi">response</span>);
|
||
|
<span class="pl-k">var</span> workbook <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-en">read</span>(data, {type<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>array<span class="pl-pds">"</span></span>});
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> DO SOMETHING WITH workbook HERE <span class="pl-c">*/</span></span>
|
||
|
}
|
||
|
|
||
|
<span class="pl-smi">req</span>.<span class="pl-c1">send</span>();</pre></div>
|
||
|
</details>
|
||
|
<details>
|
||
|
<summary><b>Browser drag-and-drop</b> (click to show)</summary>
|
||
|
<p>Drag-and-drop uses the HTML5 <code>FileReader</code> API.</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">handleDrop</span>(<span class="pl-smi">e</span>) {
|
||
|
<span class="pl-smi">e</span>.<span class="pl-c1">stopPropagation</span>(); <span class="pl-smi">e</span>.<span class="pl-c1">preventDefault</span>();
|
||
|
<span class="pl-k">var</span> files <span class="pl-k">=</span> <span class="pl-smi">e</span>.<span class="pl-smi">dataTransfer</span>.<span class="pl-smi">files</span>, f <span class="pl-k">=</span> files[<span class="pl-c1">0</span>];
|
||
|
<span class="pl-k">var</span> reader <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-en">FileReader</span>();
|
||
|
<span class="pl-smi">reader</span>.<span class="pl-en">onload</span> <span class="pl-k">=</span> <span class="pl-k">function</span>(<span class="pl-smi">e</span>) {
|
||
|
<span class="pl-k">var</span> data <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-en">Uint8Array</span>(<span class="pl-smi">e</span>.<span class="pl-c1">target</span>.<span class="pl-smi">result</span>);
|
||
|
<span class="pl-k">var</span> workbook <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-en">read</span>(data, {type<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>array<span class="pl-pds">'</span></span>});
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> DO SOMETHING WITH workbook HERE <span class="pl-c">*/</span></span>
|
||
|
};
|
||
|
<span class="pl-smi">reader</span>.<span class="pl-en">readAsArrayBuffer</span>(f);
|
||
|
}
|
||
|
<span class="pl-smi">drop_dom_element</span>.<span class="pl-c1">addEventListener</span>(<span class="pl-s"><span class="pl-pds">'</span>drop<span class="pl-pds">'</span></span>, handleDrop, <span class="pl-c1">false</span>);</pre></div>
|
||
|
</details>
|
||
|
<details>
|
||
|
<summary><b>Browser file upload form element</b> (click to show)</summary>
|
||
|
<p>Data from file input elements can be processed using the same <code>FileReader</code> API
|
||
|
as in the drag-and-drop example:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">handleFile</span>(<span class="pl-smi">e</span>) {
|
||
|
<span class="pl-k">var</span> files <span class="pl-k">=</span> <span class="pl-smi">e</span>.<span class="pl-c1">target</span>.<span class="pl-smi">files</span>, f <span class="pl-k">=</span> files[<span class="pl-c1">0</span>];
|
||
|
<span class="pl-k">var</span> reader <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-en">FileReader</span>();
|
||
|
<span class="pl-smi">reader</span>.<span class="pl-en">onload</span> <span class="pl-k">=</span> <span class="pl-k">function</span>(<span class="pl-smi">e</span>) {
|
||
|
<span class="pl-k">var</span> data <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-en">Uint8Array</span>(<span class="pl-smi">e</span>.<span class="pl-c1">target</span>.<span class="pl-smi">result</span>);
|
||
|
<span class="pl-k">var</span> workbook <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-en">read</span>(data, {type<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>array<span class="pl-pds">'</span></span>});
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> DO SOMETHING WITH workbook HERE <span class="pl-c">*/</span></span>
|
||
|
};
|
||
|
<span class="pl-smi">reader</span>.<span class="pl-en">readAsArrayBuffer</span>(f);
|
||
|
}
|
||
|
<span class="pl-smi">input_dom_element</span>.<span class="pl-c1">addEventListener</span>(<span class="pl-s"><span class="pl-pds">'</span>change<span class="pl-pds">'</span></span>, handleFile, <span class="pl-c1">false</span>);</pre></div>
|
||
|
<p>The <a href="demos/oldie/"><code>oldie</code> demo</a> shows an IE-compatible fallback scenario.</p>
|
||
|
</details>
|
||
|
<p>More specialized cases, including mobile app file processing, are covered in the
|
||
|
<a href="demos/">included demos</a></p>
|
||
|
<h3>
|
||
|
<a id="user-content-parsing-examples" class="anchor" href="#parsing-examples" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Parsing Examples</h3>
|
||
|
<ul>
|
||
|
<li>
|
||
|
<a href="http://oss.sheetjs.com/js-xlsx/" rel="nofollow">http://oss.sheetjs.com/js-xlsx/</a> HTML5 File API / Base64 Text / Web Workers</li>
|
||
|
</ul>
|
||
|
<p>Note that older versions of IE do not support HTML5 File API, so the Base64 mode
|
||
|
is used for testing.</p>
|
||
|
<details>
|
||
|
<summary><b>Get Base64 encoding on OSX / Windows</b> (click to show)</summary>
|
||
|
<p>On OSX you can get the Base64 encoding with:</p>
|
||
|
<div class="highlight highlight-source-shell"><pre>$ <span class="pl-k"><</span>target_file base64 <span class="pl-k">|</span> pbcopy</pre></div>
|
||
|
<p>On Windows XP and up you can get the Base64 encoding using <code>certutil</code>:</p>
|
||
|
<div class="highlight highlight-source-batchfile"><pre><span class="pl-k">></span> <span class="pl-k">certutil</span> -encode target_file target_file.b64</pre></div>
|
||
|
<p>(note: You have to open the file and remove the header and footer lines)</p>
|
||
|
</details>
|
||
|
<ul>
|
||
|
<li>
|
||
|
<a href="http://oss.sheetjs.com/js-xlsx/ajax.html" rel="nofollow">http://oss.sheetjs.com/js-xlsx/ajax.html</a> XMLHttpRequest</li>
|
||
|
</ul>
|
||
|
<h3>
|
||
|
<a id="user-content-streaming-read" class="anchor" href="#streaming-read" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Streaming Read</h3>
|
||
|
<details>
|
||
|
<summary><b>Why is there no Streaming Read API?</b> (click to show)</summary>
|
||
|
<p>The most common and interesting formats (XLS, XLSX/M, XLSB, ODS) are ultimately
|
||
|
ZIP or CFB containers of files. Neither format puts the directory structure at
|
||
|
the beginning of the file: ZIP files place the Central Directory records at the
|
||
|
end of the logical file, while CFB files can place the storage info anywhere in
|
||
|
the file! As a result, to properly handle these formats, a streaming function
|
||
|
would have to buffer the entire file before commencing. That belies the
|
||
|
expectations of streaming, so we do not provide any streaming read API.</p>
|
||
|
</details>
|
||
|
<p>When dealing with Readable Streams, the easiest approach is to buffer the stream
|
||
|
and process the whole thing at the end. This can be done with a temporary file
|
||
|
or by explicitly concatenating the stream:</p>
|
||
|
<details>
|
||
|
<summary><b>Explicitly concatenating streams</b> (click to show)</summary>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> fs <span class="pl-k">=</span> <span class="pl-c1">require</span>(<span class="pl-s"><span class="pl-pds">'</span>fs<span class="pl-pds">'</span></span>);
|
||
|
<span class="pl-k">var</span> <span class="pl-c1">XLSX</span> <span class="pl-k">=</span> <span class="pl-c1">require</span>(<span class="pl-s"><span class="pl-pds">'</span>xlsx<span class="pl-pds">'</span></span>);
|
||
|
<span class="pl-k">function</span> <span class="pl-en">process_RS</span>(<span class="pl-smi">stream</span><span class="pl-c"><span class="pl-c">/*</span>:ReadStream<span class="pl-c">*/</span></span>, <span class="pl-smi">cb</span><span class="pl-c"><span class="pl-c">/*</span>:(wb:Workbook)=>void<span class="pl-c">*/</span></span>)<span class="pl-c"><span class="pl-c">/*</span>:void<span class="pl-c">*/</span></span>{
|
||
|
<span class="pl-k">var</span> buffers <span class="pl-k">=</span> [];
|
||
|
<span class="pl-smi">stream</span>.<span class="pl-en">on</span>(<span class="pl-s"><span class="pl-pds">'</span>data<span class="pl-pds">'</span></span>, <span class="pl-k">function</span>(<span class="pl-smi">data</span>) { <span class="pl-smi">buffers</span>.<span class="pl-c1">push</span>(data); });
|
||
|
<span class="pl-smi">stream</span>.<span class="pl-en">on</span>(<span class="pl-s"><span class="pl-pds">'</span>end<span class="pl-pds">'</span></span>, <span class="pl-k">function</span>() {
|
||
|
<span class="pl-k">var</span> buffer <span class="pl-k">=</span> <span class="pl-smi">Buffer</span>.<span class="pl-c1">concat</span>(buffers);
|
||
|
<span class="pl-k">var</span> workbook <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-en">read</span>(buffer, {type<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>buffer<span class="pl-pds">"</span></span>});
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> DO SOMETHING WITH workbook IN THE CALLBACK <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-en">cb</span>(workbook);
|
||
|
});
|
||
|
}</pre></div>
|
||
|
<p>More robust solutions are available using modules like <code>concat-stream</code>.</p>
|
||
|
</details>
|
||
|
<details>
|
||
|
<summary><b>Writing to filesystem first</b> (click to show)</summary>
|
||
|
<p>This example uses <a href="https://npm.im/tempfile" rel="nofollow"><code>tempfile</code></a> to generate file names:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> fs <span class="pl-k">=</span> <span class="pl-c1">require</span>(<span class="pl-s"><span class="pl-pds">'</span>fs<span class="pl-pds">'</span></span>), tempfile <span class="pl-k">=</span> <span class="pl-c1">require</span>(<span class="pl-s"><span class="pl-pds">'</span>tempfile<span class="pl-pds">'</span></span>);
|
||
|
<span class="pl-k">var</span> <span class="pl-c1">XLSX</span> <span class="pl-k">=</span> <span class="pl-c1">require</span>(<span class="pl-s"><span class="pl-pds">'</span>xlsx<span class="pl-pds">'</span></span>);
|
||
|
<span class="pl-k">function</span> <span class="pl-en">process_RS</span>(<span class="pl-smi">stream</span><span class="pl-c"><span class="pl-c">/*</span>:ReadStream<span class="pl-c">*/</span></span>, <span class="pl-smi">cb</span><span class="pl-c"><span class="pl-c">/*</span>:(wb:Workbook)=>void<span class="pl-c">*/</span></span>)<span class="pl-c"><span class="pl-c">/*</span>:void<span class="pl-c">*/</span></span>{
|
||
|
<span class="pl-k">var</span> fname <span class="pl-k">=</span> <span class="pl-en">tempfile</span>(<span class="pl-s"><span class="pl-pds">'</span>.sheetjs<span class="pl-pds">'</span></span>);
|
||
|
<span class="pl-en">console</span>.<span class="pl-c1">log</span>(fname);
|
||
|
<span class="pl-k">var</span> ostream <span class="pl-k">=</span> <span class="pl-smi">fs</span>.<span class="pl-en">createWriteStream</span>(fname);
|
||
|
<span class="pl-smi">stream</span>.<span class="pl-en">pipe</span>(ostream);
|
||
|
<span class="pl-smi">ostream</span>.<span class="pl-en">on</span>(<span class="pl-s"><span class="pl-pds">'</span>finish<span class="pl-pds">'</span></span>, <span class="pl-k">function</span>() {
|
||
|
<span class="pl-k">var</span> workbook <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-en">readFile</span>(fname);
|
||
|
<span class="pl-smi">fs</span>.<span class="pl-en">unlinkSync</span>(fname);
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> DO SOMETHING WITH workbook IN THE CALLBACK <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-en">cb</span>(workbook);
|
||
|
});
|
||
|
}</pre></div>
|
||
|
</details>
|
||
|
<h2>
|
||
|
<a id="user-content-working-with-the-workbook" class="anchor" href="#working-with-the-workbook" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Working with the Workbook</h2>
|
||
|
<p>The full object format is described later in this README.</p>
|
||
|
<details>
|
||
|
<summary><b>Reading a specific cell </b> (click to show)</summary>
|
||
|
<p>This example extracts the value stored in cell A1 from the first worksheet:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> first_sheet_name <span class="pl-k">=</span> <span class="pl-smi">workbook</span>.<span class="pl-smi">SheetNames</span>[<span class="pl-c1">0</span>];
|
||
|
<span class="pl-k">var</span> address_of_cell <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">'</span>A1<span class="pl-pds">'</span></span>;
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> Get worksheet <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-k">var</span> worksheet <span class="pl-k">=</span> <span class="pl-smi">workbook</span>.<span class="pl-smi">Sheets</span>[first_sheet_name];
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> Find desired cell <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-k">var</span> desired_cell <span class="pl-k">=</span> worksheet[address_of_cell];
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> Get the value <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-k">var</span> desired_value <span class="pl-k">=</span> (desired_cell <span class="pl-k">?</span> <span class="pl-smi">desired_cell</span>.<span class="pl-smi">v</span> <span class="pl-k">:</span> <span class="pl-c1">undefined</span>);</pre></div>
|
||
|
</details>
|
||
|
<details>
|
||
|
<summary><b>Adding a new worksheet to a workbook</b> (click to show)</summary>
|
||
|
<p>This example uses <a href="#array-of-arrays-input"><code>XLSX.utils.aoa_to_sheet</code></a> to make a
|
||
|
sheet and <code>XLSX.utils.book_append_sheet</code> to append the sheet to the workbook:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> ws_name <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">"</span>SheetJS<span class="pl-pds">"</span></span>;
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> make worksheet <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-k">var</span> ws_data <span class="pl-k">=</span> [
|
||
|
[ <span class="pl-s"><span class="pl-pds">"</span>S<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>h<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>e<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>e<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>t<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>J<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>S<span class="pl-pds">"</span></span> ],
|
||
|
[ <span class="pl-c1">1</span> , <span class="pl-c1">2</span> , <span class="pl-c1">3</span> , <span class="pl-c1">4</span> , <span class="pl-c1">5</span> ]
|
||
|
];
|
||
|
<span class="pl-k">var</span> ws <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">aoa_to_sheet</span>(ws_data);
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> Add the worksheet to the workbook <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">book_append_sheet</span>(wb, ws, ws_name);</pre></div>
|
||
|
</details>
|
||
|
<details>
|
||
|
<summary><b>Creating a new workbook from scratch</b> (click to show)</summary>
|
||
|
<p>The workbook object contains a <code>SheetNames</code> array of names and a <code>Sheets</code> object
|
||
|
mapping sheet names to sheet objects. The <code>XLSX.utils.book_new</code> utility function
|
||
|
creates a new workbook object:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">/*</span> create a new blank workbook <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-k">var</span> wb <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">book_new</span>();</pre></div>
|
||
|
<p>The new workbook is blank and contains no worksheets. The write functions will
|
||
|
error if the workbook is empty.</p>
|
||
|
</details>
|
||
|
<h3>
|
||
|
<a id="user-content-parsing-and-writing-examples" class="anchor" href="#parsing-and-writing-examples" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Parsing and Writing Examples</h3>
|
||
|
<ul>
|
||
|
<li>
|
||
|
<p><a href="http://sheetjs.com/demos/modify.html" rel="nofollow">http://sheetjs.com/demos/modify.html</a> read + modify + write files</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><a href="https://github.com/SheetJS/js-xlsx/blob/master/bin/xlsx.njs">https://github.com/SheetJS/js-xlsx/blob/master/bin/xlsx.njs</a> node</p>
|
||
|
</li>
|
||
|
</ul>
|
||
|
<p>The node version installs a command line tool <code>xlsx</code> which can read spreadsheet
|
||
|
files and output the contents in various formats. The source is available at
|
||
|
<code>xlsx.njs</code> in the bin directory.</p>
|
||
|
<p>Some helper functions in <code>XLSX.utils</code> generate different views of the sheets:</p>
|
||
|
<ul>
|
||
|
<li>
|
||
|
<code>XLSX.utils.sheet_to_csv</code> generates CSV</li>
|
||
|
<li>
|
||
|
<code>XLSX.utils.sheet_to_txt</code> generates UTF16 Formatted Text</li>
|
||
|
<li>
|
||
|
<code>XLSX.utils.sheet_to_html</code> generates HTML</li>
|
||
|
<li>
|
||
|
<code>XLSX.utils.sheet_to_json</code> generates an array of objects</li>
|
||
|
<li>
|
||
|
<code>XLSX.utils.sheet_to_formulae</code> generates a list of formulae</li>
|
||
|
</ul>
|
||
|
<h2>
|
||
|
<a id="user-content-writing-workbooks" class="anchor" href="#writing-workbooks" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Writing Workbooks</h2>
|
||
|
<p>For writing, the first step is to generate output data. The helper functions
|
||
|
<code>write</code> and <code>writeFile</code> will produce the data in various formats suitable for
|
||
|
dissemination. The second step is to actual share the data with the end point.
|
||
|
Assuming <code>workbook</code> is a workbook object:</p>
|
||
|
<details>
|
||
|
<summary><b>nodejs write a file</b> (click to show)</summary>
|
||
|
<p><code>XLSX.writeFile</code> uses <code>fs.writeFileSync</code> in server environments:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">if</span>(<span class="pl-k">typeof</span> require <span class="pl-k">!==</span> <span class="pl-s"><span class="pl-pds">'</span>undefined<span class="pl-pds">'</span></span>) <span class="pl-c1">XLSX</span> <span class="pl-k">=</span> <span class="pl-c1">require</span>(<span class="pl-s"><span class="pl-pds">'</span>xlsx<span class="pl-pds">'</span></span>);
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> output format determined by filename <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-c1">XLSX</span>.<span class="pl-en">writeFile</span>(workbook, <span class="pl-s"><span class="pl-pds">'</span>out.xlsb<span class="pl-pds">'</span></span>);
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> at this point, out.xlsb is a file that you can distribute <span class="pl-c">*/</span></span></pre></div>
|
||
|
</details>
|
||
|
<details>
|
||
|
<summary><b>Photoshop ExtendScript write a file</b> (click to show)</summary>
|
||
|
<p><code>writeFile</code> wraps the <code>File</code> logic in Photoshop and other ExtendScript targets.
|
||
|
The specified path should be an absolute path:</p>
|
||
|
<div class="highlight highlight-source-js"><pre>#include <span class="pl-s"><span class="pl-pds">"</span>xlsx.extendscript.js<span class="pl-pds">"</span></span>
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> output format determined by filename <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-c1">XLSX</span>.<span class="pl-en">writeFile</span>(workbook, <span class="pl-s"><span class="pl-pds">'</span>out.xlsx<span class="pl-pds">'</span></span>);
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> at this point, out.xlsx is a file that you can distribute <span class="pl-c">*/</span></span></pre></div>
|
||
|
<p>The <a href="demos/extendscript/"><code>extendscript</code> demo</a> includes a more complex example.</p>
|
||
|
</details>
|
||
|
<details>
|
||
|
<summary><b>Browser add TABLE element to page</b> (click to show)</summary>
|
||
|
<p>The <code>sheet_to_html</code> utility function generates HTML code that can be added to
|
||
|
any DOM element.</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> worksheet <span class="pl-k">=</span> <span class="pl-smi">workbook</span>.<span class="pl-smi">Sheets</span>[<span class="pl-smi">workbook</span>.<span class="pl-smi">SheetNames</span>[<span class="pl-c1">0</span>]];
|
||
|
<span class="pl-k">var</span> container <span class="pl-k">=</span> <span class="pl-c1">document</span>.<span class="pl-c1">getElementById</span>(<span class="pl-s"><span class="pl-pds">'</span>tableau<span class="pl-pds">'</span></span>);
|
||
|
<span class="pl-smi">container</span>.<span class="pl-smi">innerHTML</span> <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">sheet_to_html</span>(worksheet);</pre></div>
|
||
|
</details>
|
||
|
<details>
|
||
|
<summary><b>Browser upload file (ajax)</b> (click to show)</summary>
|
||
|
<p>A complete example using XHR is <a href="demos/xhr/">included in the XHR demo</a>, along
|
||
|
with examples for fetch and wrapper libraries. This example assumes the server
|
||
|
can handle Base64-encoded files (see the demo for a basic nodejs server):</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">/*</span> in this example, send a base64 string to the server <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-k">var</span> wopts <span class="pl-k">=</span> { bookType<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">'</span>xlsx<span class="pl-pds">'</span></span>, bookSST<span class="pl-k">:</span><span class="pl-c1">false</span>, type<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">'</span>base64<span class="pl-pds">'</span></span> };
|
||
|
|
||
|
<span class="pl-k">var</span> wbout <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-c1">write</span>(workbook,wopts);
|
||
|
|
||
|
<span class="pl-k">var</span> req <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-en">XMLHttpRequest</span>();
|
||
|
<span class="pl-smi">req</span>.<span class="pl-c1">open</span>(<span class="pl-s"><span class="pl-pds">"</span>POST<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>/upload<span class="pl-pds">"</span></span>, <span class="pl-c1">true</span>);
|
||
|
<span class="pl-k">var</span> formdata <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-en">FormData</span>();
|
||
|
<span class="pl-smi">formdata</span>.<span class="pl-c1">append</span>(<span class="pl-s"><span class="pl-pds">'</span>file<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>test.xlsx<span class="pl-pds">'</span></span>); <span class="pl-c"><span class="pl-c">//</span> <-- server expects `file` to hold name</span>
|
||
|
<span class="pl-smi">formdata</span>.<span class="pl-c1">append</span>(<span class="pl-s"><span class="pl-pds">'</span>data<span class="pl-pds">'</span></span>, wbout); <span class="pl-c"><span class="pl-c">//</span> <-- `data` holds the base64-encoded data</span>
|
||
|
<span class="pl-smi">req</span>.<span class="pl-c1">send</span>(formdata);</pre></div>
|
||
|
</details>
|
||
|
<details>
|
||
|
<summary><b>Browser save file</b> (click to show)</summary>
|
||
|
<p><code>XLSX.writeFile</code> wraps a few techniques for triggering a file save:</p>
|
||
|
<ul>
|
||
|
<li>
|
||
|
<code>URL</code> browser API creates an object URL for the file, which the library uses
|
||
|
by creating a link and forcing a click. It is supported in modern browsers.</li>
|
||
|
<li>
|
||
|
<code>msSaveBlob</code> is an IE10+ API for triggering a file save.</li>
|
||
|
<li>
|
||
|
<code>IE_FileSave</code> uses VBScript and ActiveX to write a file in IE6+ for Windows
|
||
|
XP and Windows 7. The shim must be included in the containing HTML page.</li>
|
||
|
</ul>
|
||
|
<p>There is no standard way to determine if the actual file has been downloaded.</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">/*</span> output format determined by filename <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-c1">XLSX</span>.<span class="pl-en">writeFile</span>(workbook, <span class="pl-s"><span class="pl-pds">'</span>out.xlsb<span class="pl-pds">'</span></span>);
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> at this point, out.xlsb will have been downloaded <span class="pl-c">*/</span></span></pre></div>
|
||
|
</details>
|
||
|
<details>
|
||
|
<summary><b>Browser save file (compatibility)</b> (click to show)</summary>
|
||
|
<p><code>XLSX.writeFile</code> techniques work for most modern browsers as well as older IE.
|
||
|
For much older browsers, there are workarounds implemented by wrapper libraries.</p>
|
||
|
<p><a href="https://github.com/eligrey/FileSaver.js/"><code>FileSaver.js</code></a> implements <code>saveAs</code>.
|
||
|
Note: <code>XLSX.writeFile</code> will automatically call <code>saveAs</code> if available.</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">/*</span> bookType can be any supported output type <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-k">var</span> wopts <span class="pl-k">=</span> { bookType<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">'</span>xlsx<span class="pl-pds">'</span></span>, bookSST<span class="pl-k">:</span><span class="pl-c1">false</span>, type<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">'</span>array<span class="pl-pds">'</span></span> };
|
||
|
|
||
|
<span class="pl-k">var</span> wbout <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-c1">write</span>(workbook,wopts);
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> the saveAs call downloads a file on the local machine <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-en">saveAs</span>(<span class="pl-k">new</span> <span class="pl-en">Blob</span>([wbout],{type<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>application/octet-stream<span class="pl-pds">"</span></span>}), <span class="pl-s"><span class="pl-pds">"</span>test.xlsx<span class="pl-pds">"</span></span>);</pre></div>
|
||
|
<p><a href="https://github.com/dcneiner/downloadify"><code>Downloadify</code></a> uses a Flash SWF button
|
||
|
to generate local files, suitable for environments where ActiveX is unavailable:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-smi">Downloadify</span>.<span class="pl-en">create</span>(id,{
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> other options are required! read the downloadify docs for more info <span class="pl-c">*/</span></span>
|
||
|
filename<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>test.xlsx<span class="pl-pds">"</span></span>,
|
||
|
<span class="pl-en">data</span><span class="pl-k">:</span> <span class="pl-k">function</span>() { <span class="pl-k">return</span> <span class="pl-c1">XLSX</span>.<span class="pl-c1">write</span>(wb, {bookType<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>xlsx<span class="pl-pds">"</span></span>, type<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">'</span>base64<span class="pl-pds">'</span></span>}); },
|
||
|
append<span class="pl-k">:</span> <span class="pl-c1">false</span>,
|
||
|
dataType<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>base64<span class="pl-pds">'</span></span>
|
||
|
});</pre></div>
|
||
|
<p>The <a href="demos/oldie/"><code>oldie</code> demo</a> shows an IE-compatible fallback scenario.</p>
|
||
|
</details>
|
||
|
<p>The <a href="demos/">included demos</a> cover mobile apps and other special deployments.</p>
|
||
|
<h3>
|
||
|
<a id="user-content-writing-examples" class="anchor" href="#writing-examples" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Writing Examples</h3>
|
||
|
<ul>
|
||
|
<li>
|
||
|
<a href="http://sheetjs.com/demos/table.html" rel="nofollow">http://sheetjs.com/demos/table.html</a> exporting an HTML table</li>
|
||
|
<li>
|
||
|
<a href="http://sheetjs.com/demos/writexlsx.html" rel="nofollow">http://sheetjs.com/demos/writexlsx.html</a> generates a simple file</li>
|
||
|
</ul>
|
||
|
<h3>
|
||
|
<a id="user-content-streaming-write" class="anchor" href="#streaming-write" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Streaming Write</h3>
|
||
|
<p>The streaming write functions are available in the <code>XLSX.stream</code> object. They
|
||
|
take the same arguments as the normal write functions but return a Readable
|
||
|
Stream. They are only exposed in NodeJS.</p>
|
||
|
<ul>
|
||
|
<li>
|
||
|
<code>XLSX.stream.to_csv</code> is the streaming version of <code>XLSX.utils.sheet_to_csv</code>.</li>
|
||
|
<li>
|
||
|
<code>XLSX.stream.to_html</code> is the streaming version of <code>XLSX.utils.sheet_to_html</code>.</li>
|
||
|
<li>
|
||
|
<code>XLSX.stream.to_json</code> is the streaming version of <code>XLSX.utils.sheet_to_json</code>.</li>
|
||
|
</ul>
|
||
|
<details>
|
||
|
<summary><b>nodejs convert to CSV and write file</b> (click to show)</summary>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> output_file_name <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">"</span>out.csv<span class="pl-pds">"</span></span>;
|
||
|
<span class="pl-k">var</span> stream <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">stream</span>.<span class="pl-en">to_csv</span>(worksheet);
|
||
|
<span class="pl-smi">stream</span>.<span class="pl-en">pipe</span>(<span class="pl-smi">fs</span>.<span class="pl-en">createWriteStream</span>(output_file_name));</pre></div>
|
||
|
</details>
|
||
|
<details>
|
||
|
<summary><b>nodejs write JSON stream to screen</b> (click to show)</summary>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">/*</span> to_json returns an object-mode stream <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-k">var</span> stream <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">stream</span>.<span class="pl-en">to_json</span>(worksheet, {raw<span class="pl-k">:</span><span class="pl-c1">true</span>});
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> the following stream converts JS objects to text via JSON.stringify <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-k">var</span> conv <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-en">Transform</span>({writableObjectMode<span class="pl-k">:</span><span class="pl-c1">true</span>});
|
||
|
<span class="pl-smi">conv</span>.<span class="pl-en">_transform</span> <span class="pl-k">=</span> <span class="pl-k">function</span>(<span class="pl-smi">obj</span>, <span class="pl-smi">e</span>, <span class="pl-smi">cb</span>){ <span class="pl-en">cb</span>(<span class="pl-c1">null</span>, <span class="pl-c1">JSON</span>.<span class="pl-c1">stringify</span>(obj) <span class="pl-k">+</span> <span class="pl-s"><span class="pl-pds">"</span><span class="pl-cce">\n</span><span class="pl-pds">"</span></span>); };
|
||
|
|
||
|
<span class="pl-smi">stream</span>.<span class="pl-en">pipe</span>(conv); <span class="pl-smi">conv</span>.<span class="pl-en">pipe</span>(<span class="pl-c1">process</span>.<span class="pl-smi">stdout</span>);</pre></div>
|
||
|
</details>
|
||
|
<p><a href="https://github.com/sheetjs/sheetaki">https://github.com/sheetjs/sheetaki</a> pipes write streams to nodejs response.</p>
|
||
|
<h2>
|
||
|
<a id="user-content-interface" class="anchor" href="#interface" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Interface</h2>
|
||
|
<p><code>XLSX</code> is the exposed variable in the browser and the exported node variable</p>
|
||
|
<p><code>XLSX.version</code> is the version of the library (added by the build script).</p>
|
||
|
<p><code>XLSX.SSF</code> is an embedded version of the <a href="http://git.io/ssf" rel="nofollow">format library</a>.</p>
|
||
|
<h3>
|
||
|
<a id="user-content-parsing-functions" class="anchor" href="#parsing-functions" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Parsing functions</h3>
|
||
|
<p><code>XLSX.read(data, read_opts)</code> attempts to parse <code>data</code>.</p>
|
||
|
<p><code>XLSX.readFile(filename, read_opts)</code> attempts to read <code>filename</code> and parse.</p>
|
||
|
<p>Parse options are described in the <a href="#parsing-options">Parsing Options</a> section.</p>
|
||
|
<h3>
|
||
|
<a id="user-content-writing-functions" class="anchor" href="#writing-functions" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Writing functions</h3>
|
||
|
<p><code>XLSX.write(wb, write_opts)</code> attempts to write the workbook <code>wb</code></p>
|
||
|
<p><code>XLSX.writeFile(wb, filename, write_opts)</code> attempts to write <code>wb</code> to <code>filename</code>.
|
||
|
In browser-based environments, it will attempt to force a client-side download.</p>
|
||
|
<p><code>XLSX.writeFileAsync(filename, wb, o, cb)</code> attempts to write <code>wb</code> to <code>filename</code>.
|
||
|
If <code>o</code> is omitted, the writer will use the third argument as the callback.</p>
|
||
|
<p><code>XLSX.stream</code> contains a set of streaming write functions.</p>
|
||
|
<p>Write options are described in the <a href="#writing-options">Writing Options</a> section.</p>
|
||
|
<h3>
|
||
|
<a id="user-content-utilities" class="anchor" href="#utilities" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Utilities</h3>
|
||
|
<p>Utilities are available in the <code>XLSX.utils</code> object and are described in the
|
||
|
<a href="#utility-functions">Utility Functions</a> section:</p>
|
||
|
<p><strong>Importing:</strong></p>
|
||
|
<ul>
|
||
|
<li>
|
||
|
<code>aoa_to_sheet</code> converts an array of arrays of JS data to a worksheet.</li>
|
||
|
<li>
|
||
|
<code>json_to_sheet</code> converts an array of JS objects to a worksheet.</li>
|
||
|
<li>
|
||
|
<code>table_to_sheet</code> converts a DOM TABLE element to a worksheet.</li>
|
||
|
<li>
|
||
|
<code>sheet_add_aoa</code> adds an array of arrays of JS data to an existing worksheet.</li>
|
||
|
<li>
|
||
|
<code>sheet_add_json</code> adds an array of JS objects to an existing worksheet.</li>
|
||
|
</ul>
|
||
|
<p><strong>Exporting:</strong></p>
|
||
|
<ul>
|
||
|
<li>
|
||
|
<code>sheet_to_json</code> converts a worksheet object to an array of JSON objects.</li>
|
||
|
<li>
|
||
|
<code>sheet_to_csv</code> generates delimiter-separated-values output.</li>
|
||
|
<li>
|
||
|
<code>sheet_to_txt</code> generates UTF16 formatted text.</li>
|
||
|
<li>
|
||
|
<code>sheet_to_html</code> generates HTML output.</li>
|
||
|
<li>
|
||
|
<code>sheet_to_formulae</code> generates a list of the formulae (with value fallbacks).</li>
|
||
|
</ul>
|
||
|
<p><strong>Cell and cell address manipulation:</strong></p>
|
||
|
<ul>
|
||
|
<li>
|
||
|
<code>format_cell</code> generates the text value for a cell (using number formats).</li>
|
||
|
<li>
|
||
|
<code>encode_row / decode_row</code> converts between 0-indexed rows and 1-indexed rows.</li>
|
||
|
<li>
|
||
|
<code>encode_col / decode_col</code> converts between 0-indexed columns and column names.</li>
|
||
|
<li>
|
||
|
<code>encode_cell / decode_cell</code> converts cell addresses.</li>
|
||
|
<li>
|
||
|
<code>encode_range / decode_range</code> converts cell ranges.</li>
|
||
|
</ul>
|
||
|
<h2>
|
||
|
<a id="user-content-common-spreadsheet-format" class="anchor" href="#common-spreadsheet-format" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Common Spreadsheet Format</h2>
|
||
|
<p>js-xlsx conforms to the Common Spreadsheet Format (CSF):</p>
|
||
|
<h3>
|
||
|
<a id="user-content-general-structures" class="anchor" href="#general-structures" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>General Structures</h3>
|
||
|
<p>Cell address objects are stored as <code>{c:C, r:R}</code> where <code>C</code> and <code>R</code> are 0-indexed
|
||
|
column and row numbers, respectively. For example, the cell address <code>B5</code> is
|
||
|
represented by the object <code>{c:1, r:4}</code>.</p>
|
||
|
<p>Cell range objects are stored as <code>{s:S, e:E}</code> where <code>S</code> is the first cell and
|
||
|
<code>E</code> is the last cell in the range. The ranges are inclusive. For example, the
|
||
|
range <code>A3:B7</code> is represented by the object <code>{s:{c:0, r:2}, e:{c:1, r:6}}</code>.
|
||
|
Utility functions perform a row-major order walk traversal of a sheet range:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">for</span>(<span class="pl-k">var</span> <span class="pl-c1">R</span> <span class="pl-k">=</span> <span class="pl-smi">range</span>.<span class="pl-smi">s</span>.<span class="pl-smi">r</span>; <span class="pl-c1">R</span> <span class="pl-k"><=</span> <span class="pl-smi">range</span>.<span class="pl-smi">e</span>.<span class="pl-smi">r</span>; <span class="pl-k">++</span><span class="pl-c1">R</span>) {
|
||
|
<span class="pl-k">for</span>(<span class="pl-k">var</span> <span class="pl-c1">C</span> <span class="pl-k">=</span> <span class="pl-smi">range</span>.<span class="pl-smi">s</span>.<span class="pl-smi">c</span>; <span class="pl-c1">C</span> <span class="pl-k"><=</span> <span class="pl-smi">range</span>.<span class="pl-smi">e</span>.<span class="pl-smi">c</span>; <span class="pl-k">++</span><span class="pl-c1">C</span>) {
|
||
|
<span class="pl-k">var</span> cell_address <span class="pl-k">=</span> {c<span class="pl-k">:</span><span class="pl-c1">C</span>, r<span class="pl-k">:</span><span class="pl-c1">R</span>};
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> if an A1-style address is needed, encode the address <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-k">var</span> cell_ref <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">encode_cell</span>(cell_address);
|
||
|
}
|
||
|
}</pre></div>
|
||
|
<h3>
|
||
|
<a id="user-content-cell-object" class="anchor" href="#cell-object" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Cell Object</h3>
|
||
|
<p>Cell objects are plain JS objects with keys and values following the convention:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th>Key</th>
|
||
|
<th>Description</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td><code>v</code></td>
|
||
|
<td>raw value (see Data Types section for more info)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>w</code></td>
|
||
|
<td>formatted text (if applicable)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>t</code></td>
|
||
|
<td>type: <code>b</code> Boolean, <code>e</code> Error, <code>n</code> Number, <code>d</code> Date, <code>s</code> Text, <code>z</code> Stub</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>f</code></td>
|
||
|
<td>cell formula encoded as an A1-style string (if applicable)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>F</code></td>
|
||
|
<td>range of enclosing array if formula is array formula (if applicable)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>r</code></td>
|
||
|
<td>rich text encoding (if applicable)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>h</code></td>
|
||
|
<td>HTML rendering of the rich text (if applicable)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>c</code></td>
|
||
|
<td>comments associated with the cell</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>z</code></td>
|
||
|
<td>number format string associated with the cell (if requested)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>l</code></td>
|
||
|
<td>cell hyperlink object (<code>.Target</code> holds link, <code>.Tooltip</code> is tooltip)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>s</code></td>
|
||
|
<td>the style/theme of the cell (if applicable)</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<p>Built-in export utilities (such as the CSV exporter) will use the <code>w</code> text if it
|
||
|
is available. To change a value, be sure to delete <code>cell.w</code> (or set it to
|
||
|
<code>undefined</code>) before attempting to export. The utilities will regenerate the <code>w</code>
|
||
|
text from the number format (<code>cell.z</code>) and the raw value if possible.</p>
|
||
|
<p>The actual array formula is stored in the <code>f</code> field of the first cell in the
|
||
|
array range. Other cells in the range will omit the <code>f</code> field.</p>
|
||
|
<h4>
|
||
|
<a id="user-content-data-types" class="anchor" href="#data-types" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Data Types</h4>
|
||
|
<p>The raw value is stored in the <code>v</code> value property, interpreted based on the <code>t</code>
|
||
|
type property. This separation allows for representation of numbers as well as
|
||
|
numeric text. There are 6 valid cell types:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="center">Type</th>
|
||
|
<th align="left">Description</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="center"><code>b</code></td>
|
||
|
<td align="left">Boolean: value interpreted as JS <code>boolean</code>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="center"><code>e</code></td>
|
||
|
<td align="left">Error: value is a numeric code and <code>w</code> property stores common name **</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="center"><code>n</code></td>
|
||
|
<td align="left">Number: value is a JS <code>number</code> **</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="center"><code>d</code></td>
|
||
|
<td align="left">Date: value is a JS <code>Date</code> object or string to be parsed as Date **</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="center"><code>s</code></td>
|
||
|
<td align="left">Text: value interpreted as JS <code>string</code> and written as text **</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="center"><code>z</code></td>
|
||
|
<td align="left">Stub: blank stub cell that is ignored by data processing utilities **</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<details>
|
||
|
<summary><b>Error values and interpretation</b> (click to show)</summary>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="right">Value</th>
|
||
|
<th align="left">Error Meaning</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="right"><code>0x00</code></td>
|
||
|
<td align="left"><code>#NULL!</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right"><code>0x07</code></td>
|
||
|
<td align="left"><code>#DIV/0!</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right"><code>0x0F</code></td>
|
||
|
<td align="left"><code>#VALUE!</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right"><code>0x17</code></td>
|
||
|
<td align="left"><code>#REF!</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right"><code>0x1D</code></td>
|
||
|
<td align="left"><code>#NAME?</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right"><code>0x24</code></td>
|
||
|
<td align="left"><code>#NUM!</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right"><code>0x2A</code></td>
|
||
|
<td align="left"><code>#N/A</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right"><code>0x2B</code></td>
|
||
|
<td align="left"><code>#GETTING_DATA</code></td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
</details>
|
||
|
<p>Type <code>n</code> is the Number type. This includes all forms of data that Excel stores
|
||
|
as numbers, such as dates/times and Boolean fields. Excel exclusively uses data
|
||
|
that can be fit in an IEEE754 floating point number, just like JS Number, so the
|
||
|
<code>v</code> field holds the raw number. The <code>w</code> field holds formatted text. Dates are
|
||
|
stored as numbers by default and converted with <code>XLSX.SSF.parse_date_code</code>.</p>
|
||
|
<p>Type <code>d</code> is the Date type, generated only when the option <code>cellDates</code> is passed.
|
||
|
Since JSON does not have a natural Date type, parsers are generally expected to
|
||
|
store ISO 8601 Date strings like you would get from <code>date.toISOString()</code>. On
|
||
|
the other hand, writers and exporters should be able to handle date strings and
|
||
|
JS Date objects. Note that Excel disregards timezone modifiers and treats all
|
||
|
dates in the local timezone. The library does not correct for this error.</p>
|
||
|
<p>Type <code>s</code> is the String type. Values are explicitly stored as text. Excel will
|
||
|
interpret these cells as "number stored as text". Generated Excel files
|
||
|
automatically suppress that class of error, but other formats may elicit errors.</p>
|
||
|
<p>Type <code>z</code> represents blank stub cells. They are generated in cases where cells
|
||
|
have no assigned value but hold comments or other metadata. They are ignored by
|
||
|
the core library data processing utility functions. By default these cells are
|
||
|
not generated; the parser <code>sheetStubs</code> option must be set to <code>true</code>.</p>
|
||
|
<h4>
|
||
|
<a id="user-content-dates" class="anchor" href="#dates" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Dates</h4>
|
||
|
<details>
|
||
|
<summary><b>Excel Date Code details</b> (click to show)</summary>
|
||
|
<p>By default, Excel stores dates as numbers with a format code that specifies date
|
||
|
processing. For example, the date <code>19-Feb-17</code> is stored as the number <code>42785</code>
|
||
|
with a number format of <code>d-mmm-yy</code>. The <code>SSF</code> module understands number formats
|
||
|
and performs the appropriate conversion.</p>
|
||
|
<p>XLSX also supports a special date type <code>d</code> where the data is an ISO 8601 date
|
||
|
string. The formatter converts the date back to a number.</p>
|
||
|
<p>The default behavior for all parsers is to generate number cells. Setting
|
||
|
<code>cellDates</code> to true will force the generators to store dates.</p>
|
||
|
</details>
|
||
|
<details>
|
||
|
<summary><b>Time Zones and Dates</b> (click to show)</summary>
|
||
|
<p>Excel has no native concept of universal time. All times are specified in the
|
||
|
local time zone. Excel limitations prevent specifying true absolute dates.</p>
|
||
|
<p>Following Excel, this library treats all dates as relative to local time zone.</p>
|
||
|
</details>
|
||
|
<details>
|
||
|
<summary><b>Epochs: 1900 and 1904</b> (click to show)</summary>
|
||
|
<p>Excel supports two epochs (January 1 1900 and January 1 1904), see
|
||
|
<a href="http://support2.microsoft.com/kb/180162" rel="nofollow">"1900 vs. 1904 Date System" article</a>.
|
||
|
The workbook's epoch can be determined by examining the workbook's
|
||
|
<code>wb.Workbook.WBProps.date1904</code> property:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">!!</span>(((<span class="pl-smi">wb</span>.<span class="pl-smi">Workbook</span><span class="pl-k">||</span>{}).<span class="pl-smi">WBProps</span><span class="pl-k">||</span>{}).<span class="pl-smi">date1904</span>)</pre></div>
|
||
|
</details>
|
||
|
<h3>
|
||
|
<a id="user-content-sheet-objects" class="anchor" href="#sheet-objects" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Sheet Objects</h3>
|
||
|
<p>Each key that does not start with <code>!</code> maps to a cell (using <code>A-1</code> notation)</p>
|
||
|
<p><code>sheet[address]</code> returns the cell object for the specified address.</p>
|
||
|
<p><strong>Special sheet keys (accessible as <code>sheet[key]</code>, each starting with <code>!</code>):</strong></p>
|
||
|
<ul>
|
||
|
<li>
|
||
|
<p><code>sheet['!ref']</code>: A-1 based range representing the sheet range. Functions that
|
||
|
work with sheets should use this parameter to determine the range. Cells that
|
||
|
are assigned outside of the range are not processed. In particular, when
|
||
|
writing a sheet by hand, cells outside of the range are not included</p>
|
||
|
<p>Functions that handle sheets should test for the presence of <code>!ref</code> field.
|
||
|
If the <code>!ref</code> is omitted or is not a valid range, functions are free to treat
|
||
|
the sheet as empty or attempt to guess the range. The standard utilities that
|
||
|
ship with this library treat sheets as empty (for example, the CSV output is
|
||
|
empty string).</p>
|
||
|
<p>When reading a worksheet with the <code>sheetRows</code> property set, the ref parameter
|
||
|
will use the restricted range. The original range is set at <code>ws['!fullref']</code></p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code>sheet['!margins']</code>: Object representing the page margins. The default values
|
||
|
follow Excel's "normal" preset. Excel also has a "wide" and a "narrow" preset
|
||
|
but they are stored as raw measurements. The main properties are listed below:</p>
|
||
|
</li>
|
||
|
</ul>
|
||
|
<details>
|
||
|
<summary><b>Page margin details</b> (click to show)</summary>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th>key</th>
|
||
|
<th>description</th>
|
||
|
<th align="left">"normal"</th>
|
||
|
<th align="left">"wide"</th>
|
||
|
<th align="left">"narrow"</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td><code>left</code></td>
|
||
|
<td>left margin (inches)</td>
|
||
|
<td align="left"><code>0.7</code></td>
|
||
|
<td align="left"><code>1.0</code></td>
|
||
|
<td align="left"><code>0.25</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>right</code></td>
|
||
|
<td>right margin (inches)</td>
|
||
|
<td align="left"><code>0.7</code></td>
|
||
|
<td align="left"><code>1.0</code></td>
|
||
|
<td align="left"><code>0.25</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>top</code></td>
|
||
|
<td>top margin (inches)</td>
|
||
|
<td align="left"><code>0.75</code></td>
|
||
|
<td align="left"><code>1.0</code></td>
|
||
|
<td align="left"><code>0.75</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>bottom</code></td>
|
||
|
<td>bottom margin (inches)</td>
|
||
|
<td align="left"><code>0.75</code></td>
|
||
|
<td align="left"><code>1.0</code></td>
|
||
|
<td align="left"><code>0.75</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>header</code></td>
|
||
|
<td>header margin (inches)</td>
|
||
|
<td align="left"><code>0.3</code></td>
|
||
|
<td align="left"><code>0.5</code></td>
|
||
|
<td align="left"><code>0.3</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>footer</code></td>
|
||
|
<td>footer margin (inches)</td>
|
||
|
<td align="left"><code>0.3</code></td>
|
||
|
<td align="left"><code>0.5</code></td>
|
||
|
<td align="left"><code>0.3</code></td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">/*</span> Set worksheet sheet to "normal" <span class="pl-c">*/</span></span>
|
||
|
ws[<span class="pl-s"><span class="pl-pds">"</span>!margins<span class="pl-pds">"</span></span>]<span class="pl-k">=</span>{left<span class="pl-k">:</span><span class="pl-c1">0.7</span>, right<span class="pl-k">:</span><span class="pl-c1">0.7</span>, top<span class="pl-k">:</span><span class="pl-c1">0.75</span>,bottom<span class="pl-k">:</span><span class="pl-c1">0.75</span>,header<span class="pl-k">:</span><span class="pl-c1">0.3</span>,footer<span class="pl-k">:</span><span class="pl-c1">0.3</span>}
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> Set worksheet sheet to "wide" <span class="pl-c">*/</span></span>
|
||
|
ws[<span class="pl-s"><span class="pl-pds">"</span>!margins<span class="pl-pds">"</span></span>]<span class="pl-k">=</span>{left<span class="pl-k">:</span><span class="pl-c1">1.0</span>, right<span class="pl-k">:</span><span class="pl-c1">1.0</span>, top<span class="pl-k">:</span><span class="pl-c1">1.0</span>, bottom<span class="pl-k">:</span><span class="pl-c1">1.0</span>, header<span class="pl-k">:</span><span class="pl-c1">0.5</span>,footer<span class="pl-k">:</span><span class="pl-c1">0.5</span>}
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> Set worksheet sheet to "narrow" <span class="pl-c">*/</span></span>
|
||
|
ws[<span class="pl-s"><span class="pl-pds">"</span>!margins<span class="pl-pds">"</span></span>]<span class="pl-k">=</span>{left<span class="pl-k">:</span><span class="pl-c1">0.25</span>,right<span class="pl-k">:</span><span class="pl-c1">0.25</span>,top<span class="pl-k">:</span><span class="pl-c1">0.75</span>,bottom<span class="pl-k">:</span><span class="pl-c1">0.75</span>,header<span class="pl-k">:</span><span class="pl-c1">0.3</span>,footer<span class="pl-k">:</span><span class="pl-c1">0.3</span>}</pre></div>
|
||
|
</details>
|
||
|
<h4>
|
||
|
<a id="user-content-worksheet-object" class="anchor" href="#worksheet-object" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Worksheet Object</h4>
|
||
|
<p>In addition to the base sheet keys, worksheets also add:</p>
|
||
|
<ul>
|
||
|
<li>
|
||
|
<p><code>ws['!cols']</code>: array of column properties objects. Column widths are actually
|
||
|
stored in files in a normalized manner, measured in terms of the "Maximum
|
||
|
Digit Width" (the largest width of the rendered digits 0-9, in pixels). When
|
||
|
parsed, the column objects store the pixel width in the <code>wpx</code> field, character
|
||
|
width in the <code>wch</code> field, and the maximum digit width in the <code>MDW</code> field.</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code>ws['!rows']</code>: array of row properties objects as explained later in the docs.
|
||
|
Each row object encodes properties including row height and visibility.</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code>ws['!merges']</code>: array of range objects corresponding to the merged cells in
|
||
|
the worksheet. Plain text formats do not support merge cells. CSV export
|
||
|
will write all cells in the merge range if they exist, so be sure that only
|
||
|
the first cell (upper-left) in the range is set.</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><code>ws['!protect']</code>: object of write sheet protection properties. The <code>password</code>
|
||
|
key specifies the password for formats that support password-protected sheets
|
||
|
(XLSX/XLSB/XLS). The writer uses the XOR obfuscation method. The following
|
||
|
keys control the sheet protection -- set to <code>false</code> to enable a feature when
|
||
|
sheet is locked or set to <code>true</code> to disable a feature:</p>
|
||
|
</li>
|
||
|
</ul>
|
||
|
<details>
|
||
|
<summary><b>Worksheet Protection Details</b> (click to show)</summary>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left">key</th>
|
||
|
<th align="left">feature (true=disabled / false=enabled)</th>
|
||
|
<th align="left">default</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left"><code>selectLockedCells</code></td>
|
||
|
<td align="left">Select locked cells</td>
|
||
|
<td align="left">enabled</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>selectUnlockedCells</code></td>
|
||
|
<td align="left">Select unlocked cells</td>
|
||
|
<td align="left">enabled</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>formatCells</code></td>
|
||
|
<td align="left">Format cells</td>
|
||
|
<td align="left">disabled</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>formatColumns</code></td>
|
||
|
<td align="left">Format columns</td>
|
||
|
<td align="left">disabled</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>formatRows</code></td>
|
||
|
<td align="left">Format rows</td>
|
||
|
<td align="left">disabled</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>insertColumns</code></td>
|
||
|
<td align="left">Insert columns</td>
|
||
|
<td align="left">disabled</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>insertRows</code></td>
|
||
|
<td align="left">Insert rows</td>
|
||
|
<td align="left">disabled</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>insertHyperlinks</code></td>
|
||
|
<td align="left">Insert hyperlinks</td>
|
||
|
<td align="left">disabled</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>deleteColumns</code></td>
|
||
|
<td align="left">Delete columns</td>
|
||
|
<td align="left">disabled</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>deleteRows</code></td>
|
||
|
<td align="left">Delete rows</td>
|
||
|
<td align="left">disabled</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>sort</code></td>
|
||
|
<td align="left">Sort</td>
|
||
|
<td align="left">disabled</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>autoFilter</code></td>
|
||
|
<td align="left">Filter</td>
|
||
|
<td align="left">disabled</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>pivotTables</code></td>
|
||
|
<td align="left">Use PivotTable reports</td>
|
||
|
<td align="left">disabled</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>objects</code></td>
|
||
|
<td align="left">Edit objects</td>
|
||
|
<td align="left">enabled</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>scenarios</code></td>
|
||
|
<td align="left">Edit scenarios</td>
|
||
|
<td align="left">enabled</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
</details>
|
||
|
<ul>
|
||
|
<li>
|
||
|
<code>ws['!autofilter']</code>: AutoFilter object following the schema:</li>
|
||
|
</ul>
|
||
|
<div class="highlight highlight-source-ts"><pre><span class="pl-k">type</span> <span class="pl-en">AutoFilter</span> <span class="pl-k">=</span> {
|
||
|
ref<span class="pl-k">:</span><span class="pl-c1">string</span>; <span class="pl-c"><span class="pl-c">//</span> A-1 based range representing the AutoFilter table range</span>
|
||
|
}</pre></div>
|
||
|
<h4>
|
||
|
<a id="user-content-chartsheet-object" class="anchor" href="#chartsheet-object" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Chartsheet Object</h4>
|
||
|
<p>Chartsheets are represented as standard sheets. They are distinguished with the
|
||
|
<code>!type</code> property set to <code>"chart"</code>.</p>
|
||
|
<p>The underlying data and <code>!ref</code> refer to the cached data in the chartsheet. The
|
||
|
first row of the chartsheet is the underlying header.</p>
|
||
|
<h4>
|
||
|
<a id="user-content-macrosheet-object" class="anchor" href="#macrosheet-object" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Macrosheet Object</h4>
|
||
|
<p>Macrosheets are represented as standard sheets. They are distinguished with the
|
||
|
<code>!type</code> property set to <code>"macro"</code>.</p>
|
||
|
<h4>
|
||
|
<a id="user-content-dialogsheet-object" class="anchor" href="#dialogsheet-object" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Dialogsheet Object</h4>
|
||
|
<p>Dialogsheets are represented as standard sheets. They are distinguished with the
|
||
|
<code>!type</code> property set to <code>"dialog"</code>.</p>
|
||
|
<h3>
|
||
|
<a id="user-content-workbook-object" class="anchor" href="#workbook-object" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Workbook Object</h3>
|
||
|
<p><code>workbook.SheetNames</code> is an ordered list of the sheets in the workbook</p>
|
||
|
<p><code>wb.Sheets[sheetname]</code> returns an object representing the worksheet.</p>
|
||
|
<p><code>wb.Props</code> is an object storing the standard properties. <code>wb.Custprops</code> stores
|
||
|
custom properties. Since the XLS standard properties deviate from the XLSX
|
||
|
standard, XLS parsing stores core properties in both places.</p>
|
||
|
<p><code>wb.Workbook</code> stores <a href="#workbook-level-attributes">workbook-level attributes</a>.</p>
|
||
|
<h4>
|
||
|
<a id="user-content-workbook-file-properties" class="anchor" href="#workbook-file-properties" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Workbook File Properties</h4>
|
||
|
<p>The various file formats use different internal names for file properties. The
|
||
|
workbook <code>Props</code> object normalizes the names:</p>
|
||
|
<details>
|
||
|
<summary><b>File Properties</b> (click to show)</summary>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left">JS Name</th>
|
||
|
<th align="left">Excel Description</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left"><code>Title</code></td>
|
||
|
<td align="left">Summary tab "Title"</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>Subject</code></td>
|
||
|
<td align="left">Summary tab "Subject"</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>Author</code></td>
|
||
|
<td align="left">Summary tab "Author"</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>Manager</code></td>
|
||
|
<td align="left">Summary tab "Manager"</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>Company</code></td>
|
||
|
<td align="left">Summary tab "Company"</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>Category</code></td>
|
||
|
<td align="left">Summary tab "Category"</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>Keywords</code></td>
|
||
|
<td align="left">Summary tab "Keywords"</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>Comments</code></td>
|
||
|
<td align="left">Summary tab "Comments"</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>LastAuthor</code></td>
|
||
|
<td align="left">Statistics tab "Last saved by"</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>CreatedDate</code></td>
|
||
|
<td align="left">Statistics tab "Created"</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
</details>
|
||
|
<p>For example, to set the workbook title property:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">if</span>(<span class="pl-k">!</span><span class="pl-smi">wb</span>.<span class="pl-smi">Props</span>) <span class="pl-smi">wb</span>.<span class="pl-smi">Props</span> <span class="pl-k">=</span> {};
|
||
|
<span class="pl-smi">wb</span>.<span class="pl-smi">Props</span>.<span class="pl-smi">Title</span> <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">"</span>Insert Title Here<span class="pl-pds">"</span></span>;</pre></div>
|
||
|
<p>Custom properties are added in the workbook <code>Custprops</code> object:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">if</span>(<span class="pl-k">!</span><span class="pl-smi">wb</span>.<span class="pl-smi">Custprops</span>) <span class="pl-smi">wb</span>.<span class="pl-smi">Custprops</span> <span class="pl-k">=</span> {};
|
||
|
<span class="pl-smi">wb</span>.<span class="pl-smi">Custprops</span>[<span class="pl-s"><span class="pl-pds">"</span>Custom Property<span class="pl-pds">"</span></span>] <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">"</span>Custom Value<span class="pl-pds">"</span></span>;</pre></div>
|
||
|
<p>Writers will process the <code>Props</code> key of the options object:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">/*</span> force the Author to be "SheetJS" <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-c1">XLSX</span>.<span class="pl-c1">write</span>(wb, {Props<span class="pl-k">:</span>{Author<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>SheetJS<span class="pl-pds">"</span></span>}});</pre></div>
|
||
|
<h3>
|
||
|
<a id="user-content-workbook-level-attributes" class="anchor" href="#workbook-level-attributes" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Workbook-Level Attributes</h3>
|
||
|
<p><code>wb.Workbook</code> stores workbook-level attributes.</p>
|
||
|
<h4>
|
||
|
<a id="user-content-defined-names" class="anchor" href="#defined-names" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Defined Names</h4>
|
||
|
<p><code>wb.Workbook.Names</code> is an array of defined name objects which have the keys:</p>
|
||
|
<details>
|
||
|
<summary><b>Defined Name Properties</b> (click to show)</summary>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left">Key</th>
|
||
|
<th align="left">Description</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left"><code>Sheet</code></td>
|
||
|
<td align="left">Name scope. Sheet Index (0 = first sheet) or <code>null</code> (Workbook)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>Name</code></td>
|
||
|
<td align="left">Case-sensitive name. Standard rules apply **</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>Ref</code></td>
|
||
|
<td align="left">A1-style Reference (<code>"Sheet1!$A$1:$D$20"</code>)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>Comment</code></td>
|
||
|
<td align="left">Comment (only applicable for XLS/XLSX/XLSB)</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
</details>
|
||
|
<p>Excel allows two sheet-scoped defined names to share the same name. However, a
|
||
|
sheet-scoped name cannot collide with a workbook-scope name. Workbook writers
|
||
|
may not enforce this constraint.</p>
|
||
|
<h4>
|
||
|
<a id="user-content-workbook-views" class="anchor" href="#workbook-views" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Workbook Views</h4>
|
||
|
<p><code>wb.Workbook.Views</code> is an array of workbook view objects which have the keys:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left">Key</th>
|
||
|
<th align="left">Description</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left"><code>RTL</code></td>
|
||
|
<td align="left">If true, display right-to-left</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<h4>
|
||
|
<a id="user-content-miscellaneous-workbook-properties" class="anchor" href="#miscellaneous-workbook-properties" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Miscellaneous Workbook Properties</h4>
|
||
|
<p><code>wb.Workbook.WBProps</code> holds other workbook properties:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left">Key</th>
|
||
|
<th align="left">Description</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left"><code>CodeName</code></td>
|
||
|
<td align="left"><a href="#vba-and-macros">VBA Project Workbook Code Name</a></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>date1904</code></td>
|
||
|
<td align="left">epoch: 0/false for 1900 system, 1/true for 1904</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>filterPrivacy</code></td>
|
||
|
<td align="left">Warn or strip personally identifying info on save</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<h3>
|
||
|
<a id="user-content-document-features" class="anchor" href="#document-features" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Document Features</h3>
|
||
|
<p>Even for basic features like date storage, the official Excel formats store the
|
||
|
same content in different ways. The parsers are expected to convert from the
|
||
|
underlying file format representation to the Common Spreadsheet Format. Writers
|
||
|
are expected to convert from CSF back to the underlying file format.</p>
|
||
|
<h4>
|
||
|
<a id="user-content-formulae" class="anchor" href="#formulae" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Formulae</h4>
|
||
|
<p>The A1-style formula string is stored in the <code>f</code> field. Even though different
|
||
|
file formats store the formulae in different ways, the formats are translated.
|
||
|
Even though some formats store formulae with a leading equal sign, CSF formulae
|
||
|
do not start with <code>=</code>.</p>
|
||
|
<details>
|
||
|
<summary><b>Representation of A1=1, A2=2, A3=A1+A2</b> (click to show)</summary>
|
||
|
<div class="highlight highlight-source-js"><pre>{
|
||
|
<span class="pl-s"><span class="pl-pds">"</span>!ref<span class="pl-pds">"</span></span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>A1:A3<span class="pl-pds">"</span></span>,
|
||
|
<span class="pl-c1">A1</span><span class="pl-k">:</span> { t<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">'</span>n<span class="pl-pds">'</span></span>, v<span class="pl-k">:</span><span class="pl-c1">1</span> },
|
||
|
<span class="pl-c1">A2</span><span class="pl-k">:</span> { t<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">'</span>n<span class="pl-pds">'</span></span>, v<span class="pl-k">:</span><span class="pl-c1">2</span> },
|
||
|
<span class="pl-c1">A3</span><span class="pl-k">:</span> { t<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">'</span>n<span class="pl-pds">'</span></span>, v<span class="pl-k">:</span><span class="pl-c1">3</span>, f<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">'</span>A1+A2<span class="pl-pds">'</span></span> }
|
||
|
}</pre></div>
|
||
|
</details>
|
||
|
<p>Shared formulae are decompressed and each cell has the formula corresponding to
|
||
|
its cell. Writers generally do not attempt to generate shared formulae.</p>
|
||
|
<p>Cells with formula entries but no value will be serialized in a way that Excel
|
||
|
and other spreadsheet tools will recognize. This library will not automatically
|
||
|
compute formula results! For example, to compute <code>BESSELJ</code> in a worksheet:</p>
|
||
|
<details>
|
||
|
<summary><b>Formula without known value</b> (click to show)</summary>
|
||
|
<div class="highlight highlight-source-js"><pre>{
|
||
|
<span class="pl-s"><span class="pl-pds">"</span>!ref<span class="pl-pds">"</span></span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>A1:A3<span class="pl-pds">"</span></span>,
|
||
|
<span class="pl-c1">A1</span><span class="pl-k">:</span> { t<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">'</span>n<span class="pl-pds">'</span></span>, v<span class="pl-k">:</span><span class="pl-c1">3.14159</span> },
|
||
|
<span class="pl-c1">A2</span><span class="pl-k">:</span> { t<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">'</span>n<span class="pl-pds">'</span></span>, v<span class="pl-k">:</span><span class="pl-c1">2</span> },
|
||
|
<span class="pl-c1">A3</span><span class="pl-k">:</span> { t<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">'</span>n<span class="pl-pds">'</span></span>, f<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">'</span>BESSELJ(A1,A2)<span class="pl-pds">'</span></span> }
|
||
|
}</pre></div>
|
||
|
</details>
|
||
|
<p><strong>Array Formulae</strong></p>
|
||
|
<p>Array formulae are stored in the top-left cell of the array block. All cells
|
||
|
of an array formula have a <code>F</code> field corresponding to the range. A single-cell
|
||
|
formula can be distinguished from a plain formula by the presence of <code>F</code> field.</p>
|
||
|
<details>
|
||
|
<summary><b>Array Formula examples</b> (click to show)</summary>
|
||
|
<p>For example, setting the cell <code>C1</code> to the array formula <code>{=SUM(A1:A3*B1:B3)}</code>:</p>
|
||
|
<div class="highlight highlight-source-js"><pre>worksheet[<span class="pl-s"><span class="pl-pds">'</span>C1<span class="pl-pds">'</span></span>] <span class="pl-k">=</span> { t<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">'</span>n<span class="pl-pds">'</span></span>, f<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>SUM(A1:A3*B1:B3)<span class="pl-pds">"</span></span>, <span class="pl-c1">F</span><span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>C1:C1<span class="pl-pds">"</span></span> };</pre></div>
|
||
|
<p>For a multi-cell array formula, every cell has the same array range but only the
|
||
|
first cell specifies the formula. Consider <code>D1:D3=A1:A3*B1:B3</code>:</p>
|
||
|
<div class="highlight highlight-source-js"><pre>worksheet[<span class="pl-s"><span class="pl-pds">'</span>D1<span class="pl-pds">'</span></span>] <span class="pl-k">=</span> { t<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">'</span>n<span class="pl-pds">'</span></span>, <span class="pl-c1">F</span><span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>D1:D3<span class="pl-pds">"</span></span>, f<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>A1:A3*B1:B3<span class="pl-pds">"</span></span> };
|
||
|
worksheet[<span class="pl-s"><span class="pl-pds">'</span>D2<span class="pl-pds">'</span></span>] <span class="pl-k">=</span> { t<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">'</span>n<span class="pl-pds">'</span></span>, <span class="pl-c1">F</span><span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>D1:D3<span class="pl-pds">"</span></span> };
|
||
|
worksheet[<span class="pl-s"><span class="pl-pds">'</span>D3<span class="pl-pds">'</span></span>] <span class="pl-k">=</span> { t<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">'</span>n<span class="pl-pds">'</span></span>, <span class="pl-c1">F</span><span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>D1:D3<span class="pl-pds">"</span></span> };</pre></div>
|
||
|
</details>
|
||
|
<p>Utilities and writers are expected to check for the presence of a <code>F</code> field and
|
||
|
ignore any possible formula element <code>f</code> in cells other than the starting cell.
|
||
|
They are not expected to perform validation of the formulae!</p>
|
||
|
<details>
|
||
|
<summary><b>Formula Output Utility Function</b> (click to show)</summary>
|
||
|
<p>The <code>sheet_to_formulae</code> method generates one line per formula or array formula.
|
||
|
Array formulae are rendered in the form <code>range=formula</code> while plain cells are
|
||
|
rendered in the form <code>cell=formula or value</code>. Note that string literals are
|
||
|
prefixed with an apostrophe <code>'</code>, consistent with Excel's formula bar display.</p>
|
||
|
</details>
|
||
|
<details>
|
||
|
<summary><b>Formulae File Format Details</b> (click to show)</summary>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left">Storage Representation</th>
|
||
|
<th align="left">Formats</th>
|
||
|
<th align="center">Read</th>
|
||
|
<th align="center">Write</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left">A1-style strings</td>
|
||
|
<td align="left">XLSX</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">RC-style strings</td>
|
||
|
<td align="left">XLML and plain text</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">BIFF Parsed formulae</td>
|
||
|
<td align="left">XLSB and all XLS formats</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">OpenFormula formulae</td>
|
||
|
<td align="left">ODS/FODS/UOS</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<p>Since Excel prohibits named cells from colliding with names of A1 or RC style
|
||
|
cell references, a (not-so-simple) regex conversion is possible. BIFF Parsed
|
||
|
formulae have to be explicitly unwound. OpenFormula formulae can be converted
|
||
|
with regular expressions.</p>
|
||
|
</details>
|
||
|
<h4>
|
||
|
<a id="user-content-column-properties" class="anchor" href="#column-properties" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Column Properties</h4>
|
||
|
<p>The <code>!cols</code> array in each worksheet, if present, is a collection of <code>ColInfo</code>
|
||
|
objects which have the following properties:</p>
|
||
|
<div class="highlight highlight-source-ts"><pre><span class="pl-k">type</span> <span class="pl-en">ColInfo</span> <span class="pl-k">=</span> {
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> visibility <span class="pl-c">*/</span></span>
|
||
|
hidden<span class="pl-k">?</span><span class="pl-k">:</span> <span class="pl-c1">boolean</span>; <span class="pl-c"><span class="pl-c">//</span> if true, the column is hidden</span>
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> column width is specified in one of the following ways: <span class="pl-c">*/</span></span>
|
||
|
wpx<span class="pl-k">?</span><span class="pl-k">:</span> <span class="pl-c1">number</span>; <span class="pl-c"><span class="pl-c">//</span> width in screen pixels</span>
|
||
|
width<span class="pl-k">?</span><span class="pl-k">:</span> <span class="pl-c1">number</span>; <span class="pl-c"><span class="pl-c">//</span> width in Excel's "Max Digit Width", width*256 is integral</span>
|
||
|
wch<span class="pl-k">?</span><span class="pl-k">:</span> <span class="pl-c1">number</span>; <span class="pl-c"><span class="pl-c">//</span> width in characters</span>
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> other fields for preserving features from files <span class="pl-c">*/</span></span>
|
||
|
MDW<span class="pl-k">?</span><span class="pl-k">:</span> <span class="pl-c1">number</span>; <span class="pl-c"><span class="pl-c">//</span> Excel's "Max Digit Width" unit, always integral</span>
|
||
|
};</pre></div>
|
||
|
<details>
|
||
|
<summary><b>Why are there three width types?</b> (click to show)</summary>
|
||
|
<p>There are three different width types corresponding to the three different ways
|
||
|
spreadsheets store column widths:</p>
|
||
|
<p>SYLK and other plain text formats use raw character count. Contemporaneous tools
|
||
|
like Visicalc and Multiplan were character based. Since the characters had the
|
||
|
same width, it sufficed to store a count. This tradition was continued into the
|
||
|
BIFF formats.</p>
|
||
|
<p>SpreadsheetML (2003) tried to align with HTML by standardizing on screen pixel
|
||
|
count throughout the file. Column widths, row heights, and other measures use
|
||
|
pixels. When the pixel and character counts do not align, Excel rounds values.</p>
|
||
|
<p>XLSX internally stores column widths in a nebulous "Max Digit Width" form. The
|
||
|
Max Digit Width is the width of the largest digit when rendered (generally the
|
||
|
"0" character is the widest). The internal width must be an integer multiple of
|
||
|
the the width divided by 256. ECMA-376 describes a formula for converting
|
||
|
between pixels and the internal width. This represents a hybrid approach.</p>
|
||
|
<p>Read functions attempt to populate all three properties. Write functions will
|
||
|
try to cycle specified values to the desired type. In order to avoid potential
|
||
|
conflicts, manipulation should delete the other properties first. For example,
|
||
|
when changing the pixel width, delete the <code>wch</code> and <code>width</code> properties.</p>
|
||
|
</details>
|
||
|
<details>
|
||
|
<summary><b>Implementation details</b> (click to show)</summary>
|
||
|
<p>Given the constraints, it is possible to determine the MDW without actually
|
||
|
inspecting the font! The parsers guess the pixel width by converting from width
|
||
|
to pixels and back, repeating for all possible MDW and selecting the MDW that
|
||
|
minimizes the error. XLML actually stores the pixel width, so the guess works
|
||
|
in the opposite direction.</p>
|
||
|
<p>Even though all of the information is made available, writers are expected to
|
||
|
follow the priority order:</p>
|
||
|
<ol>
|
||
|
<li>use <code>width</code> field if available</li>
|
||
|
<li>use <code>wpx</code> pixel width if available</li>
|
||
|
<li>use <code>wch</code> character count if available</li>
|
||
|
</ol>
|
||
|
</details>
|
||
|
<h4>
|
||
|
<a id="user-content-row-properties" class="anchor" href="#row-properties" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Row Properties</h4>
|
||
|
<p>The <code>!rows</code> array in each worksheet, if present, is a collection of <code>RowInfo</code>
|
||
|
objects which have the following properties:</p>
|
||
|
<div class="highlight highlight-source-ts"><pre><span class="pl-k">type</span> <span class="pl-en">RowInfo</span> <span class="pl-k">=</span> {
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> visibility <span class="pl-c">*/</span></span>
|
||
|
hidden<span class="pl-k">?</span><span class="pl-k">:</span> <span class="pl-c1">boolean</span>; <span class="pl-c"><span class="pl-c">//</span> if true, the row is hidden</span>
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> row height is specified in one of the following ways: <span class="pl-c">*/</span></span>
|
||
|
hpx<span class="pl-k">?</span><span class="pl-k">:</span> <span class="pl-c1">number</span>; <span class="pl-c"><span class="pl-c">//</span> height in screen pixels</span>
|
||
|
hpt<span class="pl-k">?</span><span class="pl-k">:</span> <span class="pl-c1">number</span>; <span class="pl-c"><span class="pl-c">//</span> height in points</span>
|
||
|
|
||
|
level<span class="pl-k">?</span><span class="pl-k">:</span> <span class="pl-c1">number</span>; <span class="pl-c"><span class="pl-c">//</span> 0-indexed outline / group level</span>
|
||
|
};</pre></div>
|
||
|
<p>Note: Excel UI displays the base outline level as <code>1</code> and the max level as <code>8</code>.
|
||
|
The <code>level</code> field stores the base outline as <code>0</code> and the max level as <code>7</code>.</p>
|
||
|
<details>
|
||
|
<summary><b>Implementation details</b> (click to show)</summary>
|
||
|
<p>Excel internally stores row heights in points. The default resolution is 72 DPI
|
||
|
or 96 PPI, so the pixel and point size should agree. For different resolutions
|
||
|
they may not agree, so the library separates the concepts.</p>
|
||
|
<p>Even though all of the information is made available, writers are expected to
|
||
|
follow the priority order:</p>
|
||
|
<ol>
|
||
|
<li>use <code>hpx</code> pixel height if available</li>
|
||
|
<li>use <code>hpt</code> point height if available</li>
|
||
|
</ol>
|
||
|
</details>
|
||
|
<h4>
|
||
|
<a id="user-content-number-formats" class="anchor" href="#number-formats" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Number Formats</h4>
|
||
|
<p>The <code>cell.w</code> formatted text for each cell is produced from <code>cell.v</code> and <code>cell.z</code>
|
||
|
format. If the format is not specified, the Excel <code>General</code> format is used.
|
||
|
The format can either be specified as a string or as an index into the format
|
||
|
table. Parsers are expected to populate <code>workbook.SSF</code> with the number format
|
||
|
table. Writers are expected to serialize the table.</p>
|
||
|
<p>Custom tools should ensure that the local table has each used format string
|
||
|
somewhere in the table. Excel convention mandates that the custom formats start
|
||
|
at index 164. The following example creates a custom format from scratch:</p>
|
||
|
<details>
|
||
|
<summary><b>New worksheet with custom format</b> (click to show)</summary>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> wb <span class="pl-k">=</span> {
|
||
|
SheetNames<span class="pl-k">:</span> [<span class="pl-s"><span class="pl-pds">"</span>Sheet1<span class="pl-pds">"</span></span>],
|
||
|
Sheets<span class="pl-k">:</span> {
|
||
|
Sheet1<span class="pl-k">:</span> {
|
||
|
<span class="pl-s"><span class="pl-pds">"</span>!ref<span class="pl-pds">"</span></span><span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>A1:C1<span class="pl-pds">"</span></span>,
|
||
|
<span class="pl-c1">A1</span><span class="pl-k">:</span> { t<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>n<span class="pl-pds">"</span></span>, v<span class="pl-k">:</span><span class="pl-c1">10000</span> }, <span class="pl-c"><span class="pl-c">//</span> <-- General format</span>
|
||
|
<span class="pl-c1">B1</span><span class="pl-k">:</span> { t<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>n<span class="pl-pds">"</span></span>, v<span class="pl-k">:</span><span class="pl-c1">10000</span>, z<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>0%<span class="pl-pds">"</span></span> }, <span class="pl-c"><span class="pl-c">//</span> <-- Builtin format</span>
|
||
|
<span class="pl-c1">C1</span><span class="pl-k">:</span> { t<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>n<span class="pl-pds">"</span></span>, v<span class="pl-k">:</span><span class="pl-c1">10000</span>, z<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span><span class="pl-cce">\"</span>T<span class="pl-cce">\"\ </span>#0.00<span class="pl-pds">"</span></span> } <span class="pl-c"><span class="pl-c">//</span> <-- Custom format</span>
|
||
|
}
|
||
|
}
|
||
|
}</pre></div>
|
||
|
</details>
|
||
|
<p>The rules are slightly different from how Excel displays custom number formats.
|
||
|
In particular, literal characters must be wrapped in double quotes or preceded
|
||
|
by a backslash. For more info, see the Excel documentation article
|
||
|
<code>Create or delete a custom number format</code> or ECMA-376 18.8.31 (Number Formats)</p>
|
||
|
<details>
|
||
|
<summary><b>Default Number Formats</b> (click to show)</summary>
|
||
|
<p>The default formats are listed in ECMA-376 18.8.30:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="right">ID</th>
|
||
|
<th align="left">Format</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="right">0</td>
|
||
|
<td align="left"><code>General</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">1</td>
|
||
|
<td align="left"><code>0</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">2</td>
|
||
|
<td align="left"><code>0.00</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">3</td>
|
||
|
<td align="left"><code>#,##0</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">4</td>
|
||
|
<td align="left"><code>#,##0.00</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">9</td>
|
||
|
<td align="left"><code>0%</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">10</td>
|
||
|
<td align="left"><code>0.00%</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">11</td>
|
||
|
<td align="left"><code>0.00E+00</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">12</td>
|
||
|
<td align="left"><code># ?/?</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">13</td>
|
||
|
<td align="left"><code># ??/??</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">14</td>
|
||
|
<td align="left">
|
||
|
<code>m/d/yy</code> (see below)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">15</td>
|
||
|
<td align="left"><code>d-mmm-yy</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">16</td>
|
||
|
<td align="left"><code>d-mmm</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">17</td>
|
||
|
<td align="left"><code>mmm-yy</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">18</td>
|
||
|
<td align="left"><code>h:mm AM/PM</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">19</td>
|
||
|
<td align="left"><code>h:mm:ss AM/PM</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">20</td>
|
||
|
<td align="left"><code>h:mm</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">21</td>
|
||
|
<td align="left"><code>h:mm:ss</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">22</td>
|
||
|
<td align="left"><code>m/d/yy h:mm</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">37</td>
|
||
|
<td align="left"><code>#,##0 ;(#,##0)</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">38</td>
|
||
|
<td align="left"><code>#,##0 ;[Red](#,##0)</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">39</td>
|
||
|
<td align="left"><code>#,##0.00;(#,##0.00)</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">40</td>
|
||
|
<td align="left"><code>#,##0.00;[Red](#,##0.00)</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">45</td>
|
||
|
<td align="left"><code>mm:ss</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">46</td>
|
||
|
<td align="left"><code>[h]:mm:ss</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">47</td>
|
||
|
<td align="left"><code>mmss.0</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">48</td>
|
||
|
<td align="left"><code>##0.0E+0</code></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="right">49</td>
|
||
|
<td align="left"><code>@</code></td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
</details>
|
||
|
<p>Format 14 (<code>m/d/yy</code>) is localized by Excel: even though the file specifies that
|
||
|
number format, it will be drawn differently based on system settings. It makes
|
||
|
sense when the producer and consumer of files are in the same locale, but that
|
||
|
is not always the case over the Internet. To get around this ambiguity, parse
|
||
|
functions accept the <code>dateNF</code> option to override the interpretation of that
|
||
|
specific format string.</p>
|
||
|
<h4>
|
||
|
<a id="user-content-hyperlinks" class="anchor" href="#hyperlinks" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Hyperlinks</h4>
|
||
|
<p>Hyperlinks are stored in the <code>l</code> key of cell objects. The <code>Target</code> field of the
|
||
|
hyperlink object is the target of the link, including the URI fragment. Tooltips
|
||
|
are stored in the <code>Tooltip</code> field and are displayed when you move your mouse
|
||
|
over the text.</p>
|
||
|
<p>For example, the following snippet creates a link from cell <code>A3</code> to
|
||
|
<a href="http://sheetjs.com" rel="nofollow">http://sheetjs.com</a> with the tip <code>"Find us @ SheetJS.com!"</code>:</p>
|
||
|
<div class="highlight highlight-source-js"><pre>ws[<span class="pl-s"><span class="pl-pds">'</span>A3<span class="pl-pds">'</span></span>].<span class="pl-smi">l</span> <span class="pl-k">=</span> { Target<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>http://sheetjs.com<span class="pl-pds">"</span></span>, Tooltip<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>Find us @ SheetJS.com!<span class="pl-pds">"</span></span> };</pre></div>
|
||
|
<p>Note that Excel does not automatically style hyperlinks -- they will generally
|
||
|
be displayed as normal text.</p>
|
||
|
<p>Links where the target is a cell or range or defined name in the same workbook
|
||
|
("Internal Links") are marked with a leading hash character:</p>
|
||
|
<div class="highlight highlight-source-js"><pre>ws[<span class="pl-s"><span class="pl-pds">'</span>A2<span class="pl-pds">'</span></span>].<span class="pl-smi">l</span> <span class="pl-k">=</span> { Target<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>#E2<span class="pl-pds">"</span></span> }; <span class="pl-c"><span class="pl-c">/*</span> link to cell E2 <span class="pl-c">*/</span></span></pre></div>
|
||
|
<h4>
|
||
|
<a id="user-content-cell-comments" class="anchor" href="#cell-comments" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Cell Comments</h4>
|
||
|
<p>Cell comments are objects stored in the <code>c</code> array of cell objects. The actual
|
||
|
contents of the comment are split into blocks based on the comment author. The
|
||
|
<code>a</code> field of each comment object is the author of the comment and the <code>t</code> field
|
||
|
is the plain text representation.</p>
|
||
|
<p>For example, the following snippet appends a cell comment into cell <code>A1</code>:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">if</span>(<span class="pl-k">!</span><span class="pl-smi">ws</span>.<span class="pl-c1">A1</span>.<span class="pl-smi">c</span>) <span class="pl-smi">ws</span>.<span class="pl-c1">A1</span>.<span class="pl-smi">c</span> <span class="pl-k">=</span> [];
|
||
|
<span class="pl-smi">ws</span>.<span class="pl-c1">A1</span>.<span class="pl-smi">c</span>.<span class="pl-c1">push</span>({a<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>SheetJS<span class="pl-pds">"</span></span>, t<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>I'm a little comment, short and stout!<span class="pl-pds">"</span></span>});</pre></div>
|
||
|
<p>Note: XLSB enforces a 54 character limit on the Author name. Names longer than
|
||
|
54 characters may cause issues with other formats.</p>
|
||
|
<p>To mark a comment as normally hidden, set the <code>hidden</code> property:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">if</span>(<span class="pl-k">!</span><span class="pl-smi">ws</span>.<span class="pl-c1">A1</span>.<span class="pl-smi">c</span>) <span class="pl-smi">ws</span>.<span class="pl-c1">A1</span>.<span class="pl-smi">c</span> <span class="pl-k">=</span> [];
|
||
|
<span class="pl-smi">ws</span>.<span class="pl-c1">A1</span>.<span class="pl-smi">c</span>.<span class="pl-c1">push</span>({a<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>SheetJS<span class="pl-pds">"</span></span>, t<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>This comment is visible<span class="pl-pds">"</span></span>});
|
||
|
|
||
|
<span class="pl-k">if</span>(<span class="pl-k">!</span><span class="pl-smi">ws</span>.<span class="pl-c1">A2</span>.<span class="pl-smi">c</span>) <span class="pl-smi">ws</span>.<span class="pl-c1">A2</span>.<span class="pl-smi">c</span> <span class="pl-k">=</span> [];
|
||
|
<span class="pl-smi">ws</span>.<span class="pl-c1">A2</span>.<span class="pl-smi">c</span>.<span class="pl-smi">hidden</span> <span class="pl-k">=</span> <span class="pl-c1">true</span>;
|
||
|
<span class="pl-smi">ws</span>.<span class="pl-c1">A2</span>.<span class="pl-smi">c</span>.<span class="pl-c1">push</span>({a<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>SheetJS<span class="pl-pds">"</span></span>, t<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>This comment will be hidden<span class="pl-pds">"</span></span>});</pre></div>
|
||
|
<h4>
|
||
|
<a id="user-content-sheet-visibility" class="anchor" href="#sheet-visibility" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Sheet Visibility</h4>
|
||
|
<p>Excel enables hiding sheets in the lower tab bar. The sheet data is stored in
|
||
|
the file but the UI does not readily make it available. Standard hidden sheets
|
||
|
are revealed in the "Unhide" menu. Excel also has "very hidden" sheets which
|
||
|
cannot be revealed in the menu. It is only accessible in the VB Editor!</p>
|
||
|
<p>The visibility setting is stored in the <code>Hidden</code> property of sheet props array.</p>
|
||
|
<details>
|
||
|
<summary><b>More details</b> (click to show)</summary>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="center">Value</th>
|
||
|
<th align="left">Definition</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="center">0</td>
|
||
|
<td align="left">Visible</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="center">1</td>
|
||
|
<td align="left">Hidden</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="center">2</td>
|
||
|
<td align="left">Very Hidden</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<p>With <a href="https://rawgit.com/SheetJS/test_files/master/sheet_visibility.xlsx" rel="nofollow">https://rawgit.com/SheetJS/test_files/master/sheet_visibility.xlsx</a>:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">></span> <span class="pl-smi">wb</span>.<span class="pl-smi">Workbook</span>.<span class="pl-smi">Sheets</span>.<span class="pl-en">map</span>(<span class="pl-k">function</span>(<span class="pl-smi">x</span>) { <span class="pl-k">return</span> [<span class="pl-smi">x</span>.<span class="pl-c1">name</span>, <span class="pl-smi">x</span>.<span class="pl-smi">Hidden</span>] })
|
||
|
[ [ <span class="pl-s"><span class="pl-pds">'</span>Visible<span class="pl-pds">'</span></span>, <span class="pl-c1">0</span> ], [ <span class="pl-s"><span class="pl-pds">'</span>Hidden<span class="pl-pds">'</span></span>, <span class="pl-c1">1</span> ], [ <span class="pl-s"><span class="pl-pds">'</span>VeryHidden<span class="pl-pds">'</span></span>, <span class="pl-c1">2</span> ] ]</pre></div>
|
||
|
<p>Non-Excel formats do not support the Very Hidden state. The best way to test
|
||
|
if a sheet is visible is to check if the <code>Hidden</code> property is logical truth:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">></span> <span class="pl-smi">wb</span>.<span class="pl-smi">Workbook</span>.<span class="pl-smi">Sheets</span>.<span class="pl-en">map</span>(<span class="pl-k">function</span>(<span class="pl-smi">x</span>) { <span class="pl-k">return</span> [<span class="pl-smi">x</span>.<span class="pl-c1">name</span>, <span class="pl-k">!</span><span class="pl-smi">x</span>.<span class="pl-smi">Hidden</span>] })
|
||
|
[ [ <span class="pl-s"><span class="pl-pds">'</span>Visible<span class="pl-pds">'</span></span>, <span class="pl-c1">true</span> ], [ <span class="pl-s"><span class="pl-pds">'</span>Hidden<span class="pl-pds">'</span></span>, <span class="pl-c1">false</span> ], [ <span class="pl-s"><span class="pl-pds">'</span>VeryHidden<span class="pl-pds">'</span></span>, <span class="pl-c1">false</span> ] ]</pre></div>
|
||
|
</details>
|
||
|
<h4>
|
||
|
<a id="user-content-vba-and-macros" class="anchor" href="#vba-and-macros" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>VBA and Macros</h4>
|
||
|
<p>VBA Macros are stored in a special data blob that is exposed in the <code>vbaraw</code>
|
||
|
property of the workbook object when the <code>bookVBA</code> option is <code>true</code>. They are
|
||
|
supported in <code>XLSM</code>, <code>XLSB</code>, and <code>BIFF8 XLS</code> formats. The supported format
|
||
|
writers automatically insert the data blobs if it is present in the workbook and
|
||
|
associate with the worksheet names.</p>
|
||
|
<details>
|
||
|
<summary><b>Custom Code Names</b> (click to show)</summary>
|
||
|
<p>The workbook code name is stored in <code>wb.Workbook.WBProps.CodeName</code>. By default,
|
||
|
Excel will write <code>ThisWorkbook</code> or a translated phrase like <code>DieseArbeitsmappe</code>.
|
||
|
Worksheet and Chartsheet code names are in the worksheet properties object at
|
||
|
<code>wb.Workbook.Sheets[i].CodeName</code>. Macrosheets and Dialogsheets are ignored.</p>
|
||
|
<p>The readers and writers preserve the code names, but they have to be manually
|
||
|
set when adding a VBA blob to a different workbook.</p>
|
||
|
</details>
|
||
|
<details>
|
||
|
<summary><b>Macrosheets</b> (click to show)</summary>
|
||
|
<p>Older versions of Excel also supported a non-VBA "macrosheet" sheet type that
|
||
|
stored automation commands. These are exposed in objects with the <code>!type</code>
|
||
|
property set to <code>"macro"</code>.</p>
|
||
|
</details>
|
||
|
<details>
|
||
|
<summary><b>Detecting macros in workbooks</b> (click to show)</summary>
|
||
|
<p>The <code>vbaraw</code> field will only be set if macros are present, so testing is simple:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">function</span> <span class="pl-en">wb_has_macro</span>(<span class="pl-smi">wb</span><span class="pl-c"><span class="pl-c">/*</span>:workbook<span class="pl-c">*/</span></span>)<span class="pl-c"><span class="pl-c">/*</span>:boolean<span class="pl-c">*/</span></span> {
|
||
|
<span class="pl-k">if</span>(<span class="pl-k">!!</span><span class="pl-smi">wb</span>.<span class="pl-smi">vbaraw</span>) <span class="pl-k">return</span> <span class="pl-c1">true</span>;
|
||
|
<span class="pl-k">const</span> <span class="pl-c1">sheets</span> <span class="pl-k">=</span> <span class="pl-smi">wb</span>.<span class="pl-smi">SheetNames</span>.<span class="pl-en">map</span>((<span class="pl-smi">n</span>) <span class="pl-k">=></span> <span class="pl-smi">wb</span>.<span class="pl-smi">Sheets</span>[n]);
|
||
|
<span class="pl-k">return</span> <span class="pl-smi">sheets</span>.<span class="pl-en">some</span>((<span class="pl-smi">ws</span>) <span class="pl-k">=></span> <span class="pl-k">!!</span>ws <span class="pl-k">&&</span> ws[<span class="pl-s"><span class="pl-pds">'</span>!type<span class="pl-pds">'</span></span>]<span class="pl-k">==</span><span class="pl-s"><span class="pl-pds">'</span>macro<span class="pl-pds">'</span></span>);
|
||
|
}</pre></div>
|
||
|
</details>
|
||
|
<h2>
|
||
|
<a id="user-content-parsing-options" class="anchor" href="#parsing-options" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Parsing Options</h2>
|
||
|
<p>The exported <code>read</code> and <code>readFile</code> functions accept an options argument:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left">Option Name</th>
|
||
|
<th align="right">Default</th>
|
||
|
<th align="left">Description</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left"><code>type</code></td>
|
||
|
<td align="right"></td>
|
||
|
<td align="left">Input data encoding (see Input Type below)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>raw</code></td>
|
||
|
<td align="right">false</td>
|
||
|
<td align="left">If true, plain text parsing will not parse values **</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>codepage</code></td>
|
||
|
<td align="right"></td>
|
||
|
<td align="left">If specified, use code page when appropriate **</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>cellFormula</code></td>
|
||
|
<td align="right">true</td>
|
||
|
<td align="left">Save formulae to the .f field</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>cellHTML</code></td>
|
||
|
<td align="right">true</td>
|
||
|
<td align="left">Parse rich text and save HTML to the <code>.h</code> field</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>cellNF</code></td>
|
||
|
<td align="right">false</td>
|
||
|
<td align="left">Save number format string to the <code>.z</code> field</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>cellStyles</code></td>
|
||
|
<td align="right">false</td>
|
||
|
<td align="left">Save style/theme info to the <code>.s</code> field</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>cellText</code></td>
|
||
|
<td align="right">true</td>
|
||
|
<td align="left">Generated formatted text to the <code>.w</code> field</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>cellDates</code></td>
|
||
|
<td align="right">false</td>
|
||
|
<td align="left">Store dates as type <code>d</code> (default is <code>n</code>)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>dateNF</code></td>
|
||
|
<td align="right"></td>
|
||
|
<td align="left">If specified, use the string for date code 14 **</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>sheetStubs</code></td>
|
||
|
<td align="right">false</td>
|
||
|
<td align="left">Create cell objects of type <code>z</code> for stub cells</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>sheetRows</code></td>
|
||
|
<td align="right">0</td>
|
||
|
<td align="left">If >0, read the first <code>sheetRows</code> rows **</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>bookDeps</code></td>
|
||
|
<td align="right">false</td>
|
||
|
<td align="left">If true, parse calculation chains</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>bookFiles</code></td>
|
||
|
<td align="right">false</td>
|
||
|
<td align="left">If true, add raw files to book object **</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>bookProps</code></td>
|
||
|
<td align="right">false</td>
|
||
|
<td align="left">If true, only parse enough to get book metadata **</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>bookSheets</code></td>
|
||
|
<td align="right">false</td>
|
||
|
<td align="left">If true, only parse enough to get the sheet names</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>bookVBA</code></td>
|
||
|
<td align="right">false</td>
|
||
|
<td align="left">If true, copy VBA blob to <code>vbaraw</code> field **</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>password</code></td>
|
||
|
<td align="right">""</td>
|
||
|
<td align="left">If defined and file is encrypted, use password **</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>WTF</code></td>
|
||
|
<td align="right">false</td>
|
||
|
<td align="left">If true, throw errors on unexpected file features **</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>sheets</code></td>
|
||
|
<td align="right"></td>
|
||
|
<td align="left">If specified, only parse specified sheets **</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<ul>
|
||
|
<li>Even if <code>cellNF</code> is false, formatted text will be generated and saved to <code>.w</code>
|
||
|
</li>
|
||
|
<li>In some cases, sheets may be parsed even if <code>bookSheets</code> is false.</li>
|
||
|
<li>Excel aggressively tries to interpret values from CSV and other plain text.
|
||
|
This leads to surprising behavior! The <code>raw</code> option suppresses value parsing.</li>
|
||
|
<li>
|
||
|
<code>bookSheets</code> and <code>bookProps</code> combine to give both sets of information</li>
|
||
|
<li>
|
||
|
<code>Deps</code> will be an empty object if <code>bookDeps</code> is false</li>
|
||
|
<li>
|
||
|
<code>bookFiles</code> behavior depends on file type:
|
||
|
<ul>
|
||
|
<li>
|
||
|
<code>keys</code> array (paths in the ZIP) for ZIP-based formats</li>
|
||
|
<li>
|
||
|
<code>files</code> hash (mapping paths to objects representing the files) for ZIP</li>
|
||
|
<li>
|
||
|
<code>cfb</code> object for formats using CFB containers</li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>
|
||
|
<code>sheetRows-1</code> rows will be generated when looking at the JSON object output
|
||
|
(since the header row is counted as a row when parsing the data)</li>
|
||
|
<li>By default all worksheets are parsed. <code>sheets</code> restricts based on input type:
|
||
|
<ul>
|
||
|
<li>number: zero-based index of worksheet to parse (<code>0</code> is first worksheet)</li>
|
||
|
<li>string: name of worksheet to parse (case insensitive)</li>
|
||
|
<li>array of numbers and strings to select multiple worksheets.</li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>
|
||
|
<code>bookVBA</code> merely exposes the raw VBA CFB object. It does not parse the data.
|
||
|
XLSM and XLSB store the VBA CFB object in <code>xl/vbaProject.bin</code>. BIFF8 XLS mixes
|
||
|
the VBA entries alongside the core Workbook entry, so the library generates a
|
||
|
new XLSB-compatible blob from the XLS CFB container.</li>
|
||
|
<li>
|
||
|
<code>codepage</code> is applied to BIFF2 - BIFF5 files without <code>CodePage</code> records and to
|
||
|
CSV files without BOM in <code>type:"binary"</code>. BIFF8 XLS always defaults to 1200.</li>
|
||
|
<li>Currently only XOR encryption is supported. Unsupported error will be thrown
|
||
|
for files employing other encryption methods.</li>
|
||
|
<li>WTF is mainly for development. By default, the parser will suppress read
|
||
|
errors on single worksheets, allowing you to read from the worksheets that do
|
||
|
parse properly. Setting <code>WTF:1</code> forces those errors to be thrown.</li>
|
||
|
</ul>
|
||
|
<h3>
|
||
|
<a id="user-content-input-type" class="anchor" href="#input-type" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Input Type</h3>
|
||
|
<p>Strings can be interpreted in multiple ways. The <code>type</code> parameter for <code>read</code>
|
||
|
tells the library how to parse the data argument:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th><code>type</code></th>
|
||
|
<th>expected input</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td><code>"base64"</code></td>
|
||
|
<td>string: Base64 encoding of the file</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>"binary"</code></td>
|
||
|
<td>string: binary string (byte <code>n</code> is <code>data.charCodeAt(n)</code>)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>"string"</code></td>
|
||
|
<td>string: JS string (characters interpreted as UTF8)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>"buffer"</code></td>
|
||
|
<td>nodejs Buffer</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>"array"</code></td>
|
||
|
<td>array: array of 8-bit unsigned int (byte <code>n</code> is <code>data[n]</code>)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>"file"</code></td>
|
||
|
<td>string: path of file that will be read (nodejs only)</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<h3>
|
||
|
<a id="user-content-guessing-file-type" class="anchor" href="#guessing-file-type" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Guessing File Type</h3>
|
||
|
<details>
|
||
|
<summary><b>Implementation Details</b> (click to show)</summary>
|
||
|
<p>Excel and other spreadsheet tools read the first few bytes and apply other
|
||
|
heuristics to determine a file type. This enables file type punning: renaming
|
||
|
files with the <code>.xls</code> extension will tell your computer to use Excel to open the
|
||
|
file but Excel will know how to handle it. This library applies similar logic:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left">Byte 0</th>
|
||
|
<th align="left">Raw File Type</th>
|
||
|
<th align="left">Spreadsheet Types</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left"><code>0xD0</code></td>
|
||
|
<td align="left">CFB Container</td>
|
||
|
<td align="left">BIFF 5/8 or password-protected XLSX/XLSB or WQ3/QPW</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>0x09</code></td>
|
||
|
<td align="left">BIFF Stream</td>
|
||
|
<td align="left">BIFF 2/3/4/5</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>0x3C</code></td>
|
||
|
<td align="left">XML/HTML</td>
|
||
|
<td align="left">SpreadsheetML / Flat ODS / UOS1 / HTML / plain text</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>0x50</code></td>
|
||
|
<td align="left">ZIP Archive</td>
|
||
|
<td align="left">XLSB or XLSX/M or ODS or UOS2 or plain text</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>0x49</code></td>
|
||
|
<td align="left">Plain Text</td>
|
||
|
<td align="left">SYLK or plain text</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>0x54</code></td>
|
||
|
<td align="left">Plain Text</td>
|
||
|
<td align="left">DIF or plain text</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>0xEF</code></td>
|
||
|
<td align="left">UTF8 Encoded</td>
|
||
|
<td align="left">SpreadsheetML / Flat ODS / UOS1 / HTML / plain text</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>0xFF</code></td>
|
||
|
<td align="left">UTF16 Encoded</td>
|
||
|
<td align="left">SpreadsheetML / Flat ODS / UOS1 / HTML / plain text</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>0x00</code></td>
|
||
|
<td align="left">Record Stream</td>
|
||
|
<td align="left">Lotus WK* or Quattro Pro or plain text</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>0x7B</code></td>
|
||
|
<td align="left">Plain text</td>
|
||
|
<td align="left">RTF or plain text</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>0x0A</code></td>
|
||
|
<td align="left">Plain text</td>
|
||
|
<td align="left">SpreadsheetML / Flat ODS / UOS1 / HTML / plain text</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>0x0D</code></td>
|
||
|
<td align="left">Plain text</td>
|
||
|
<td align="left">SpreadsheetML / Flat ODS / UOS1 / HTML / plain text</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>0x20</code></td>
|
||
|
<td align="left">Plain text</td>
|
||
|
<td align="left">SpreadsheetML / Flat ODS / UOS1 / HTML / plain text</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<p>DBF files are detected based on the first byte as well as the third and fourth
|
||
|
bytes (corresponding to month and day of the file date)</p>
|
||
|
<p>Plain text format guessing follows the priority order:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left">Format</th>
|
||
|
<th align="left">Test</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left">XML</td>
|
||
|
<td align="left">
|
||
|
<code><?xml</code> appears in the first 1024 characters</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">HTML</td>
|
||
|
<td align="left">starts with <code><</code> and HTML tags appear in the first 1024 characters *</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">XML</td>
|
||
|
<td align="left">starts with <code><</code>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">RTF</td>
|
||
|
<td align="left">starts with <code>{\rt</code>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">DSV</td>
|
||
|
<td align="left">starts with <code>/sep=.$/</code>, separator is the specified character</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">DSV</td>
|
||
|
<td align="left">more unquoted <code>";"</code> chars than <code>"\t"</code> or <code>","</code> in the first 1024</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">TSV</td>
|
||
|
<td align="left">more unquoted <code>"\t"</code> chars than <code>","</code> chars in the first 1024</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">CSV</td>
|
||
|
<td align="left">one of the first 1024 characters is a comma <code>","</code>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">ETH</td>
|
||
|
<td align="left">starts with <code>socialcalc:version:</code>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">PRN</td>
|
||
|
<td align="left">(default)</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<ul>
|
||
|
<li>HTML tags include: <code>html</code>, <code>table</code>, <code>head</code>, <code>meta</code>, <code>script</code>, <code>style</code>, <code>div</code>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</details>
|
||
|
<details>
|
||
|
<summary><b>Why are random text files valid?</b> (click to show)</summary>
|
||
|
<p>Excel is extremely aggressive in reading files. Adding an XLS extension to any
|
||
|
display text file (where the only characters are ANSI display chars) tricks
|
||
|
Excel into thinking that the file is potentially a CSV or TSV file, even if it
|
||
|
is only one column! This library attempts to replicate that behavior.</p>
|
||
|
<p>The best approach is to validate the desired worksheet and ensure it has the
|
||
|
expected number of rows or columns. Extracting the range is extremely simple:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> range <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">decode_range</span>(worksheet[<span class="pl-s"><span class="pl-pds">'</span>!ref<span class="pl-pds">'</span></span>]);
|
||
|
<span class="pl-k">var</span> ncols <span class="pl-k">=</span> <span class="pl-smi">range</span>.<span class="pl-smi">e</span>.<span class="pl-smi">c</span> <span class="pl-k">-</span> <span class="pl-smi">range</span>.<span class="pl-smi">s</span>.<span class="pl-smi">c</span> <span class="pl-k">+</span> <span class="pl-c1">1</span>, nrows <span class="pl-k">=</span> <span class="pl-smi">range</span>.<span class="pl-smi">e</span>.<span class="pl-smi">r</span> <span class="pl-k">-</span> <span class="pl-smi">range</span>.<span class="pl-smi">s</span>.<span class="pl-smi">r</span> <span class="pl-k">+</span> <span class="pl-c1">1</span>;</pre></div>
|
||
|
</details>
|
||
|
<h2>
|
||
|
<a id="user-content-writing-options" class="anchor" href="#writing-options" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Writing Options</h2>
|
||
|
<p>The exported <code>write</code> and <code>writeFile</code> functions accept an options argument:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left">Option Name</th>
|
||
|
<th align="right">Default</th>
|
||
|
<th align="left">Description</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left"><code>type</code></td>
|
||
|
<td align="right"></td>
|
||
|
<td align="left">Output data encoding (see Output Type below)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>cellDates</code></td>
|
||
|
<td align="right"><code>false</code></td>
|
||
|
<td align="left">Store dates as type <code>d</code> (default is <code>n</code>)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>bookSST</code></td>
|
||
|
<td align="right"><code>false</code></td>
|
||
|
<td align="left">Generate Shared String Table **</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>bookType</code></td>
|
||
|
<td align="right"><code>"xlsx"</code></td>
|
||
|
<td align="left">Type of Workbook (see below for supported formats)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>sheet</code></td>
|
||
|
<td align="right"><code>""</code></td>
|
||
|
<td align="left">Name of Worksheet for single-sheet formats **</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>compression</code></td>
|
||
|
<td align="right"><code>false</code></td>
|
||
|
<td align="left">Use ZIP compression for ZIP-based formats **</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>Props</code></td>
|
||
|
<td align="right"></td>
|
||
|
<td align="left">Override workbook properties when writing **</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>themeXLSX</code></td>
|
||
|
<td align="right"></td>
|
||
|
<td align="left">Override theme XML when writing XLSX/XLSB/XLSM **</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>ignoreEC</code></td>
|
||
|
<td align="right"><code>true</code></td>
|
||
|
<td align="left">Suppress "number as text" errors **</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<ul>
|
||
|
<li>
|
||
|
<code>bookSST</code> is slower and more memory intensive, but has better compatibility
|
||
|
with older versions of iOS Numbers</li>
|
||
|
<li>The raw data is the only thing guaranteed to be saved. Features not described
|
||
|
in this README may not be serialized.</li>
|
||
|
<li>
|
||
|
<code>cellDates</code> only applies to XLSX output and is not guaranteed to work with
|
||
|
third-party readers. Excel itself does not usually write cells with type <code>d</code>
|
||
|
so non-Excel tools may ignore the data or error in the presence of dates.</li>
|
||
|
<li>
|
||
|
<code>Props</code> is an object mirroring the workbook <code>Props</code> field. See the table from
|
||
|
the <a href="#workbook-file-properties">Workbook File Properties</a> section.</li>
|
||
|
<li>if specified, the string from <code>themeXLSX</code> will be saved as the primary theme
|
||
|
for XLSX/XLSB/XLSM files (to <code>xl/theme/theme1.xml</code> in the ZIP)</li>
|
||
|
<li>Due to a bug in the program, some features like "Text to Columns" will crash
|
||
|
Excel on worksheets where error conditions are ignored. The writer will mark
|
||
|
files to ignore the error by default. Set <code>ignoreEC</code> to <code>false</code> to suppress.</li>
|
||
|
</ul>
|
||
|
<h3>
|
||
|
<a id="user-content-supported-output-formats" class="anchor" href="#supported-output-formats" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Supported Output Formats</h3>
|
||
|
<p>For broad compatibility with third-party tools, this library supports many
|
||
|
output formats. The specific file type is controlled with <code>bookType</code> option:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left"><code>bookType</code></th>
|
||
|
<th align="right">file ext</th>
|
||
|
<th align="center">container</th>
|
||
|
<th align="left">sheets</th>
|
||
|
<th align="left">Description</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left"><code>xlsx</code></td>
|
||
|
<td align="right"><code>.xlsx</code></td>
|
||
|
<td align="center">ZIP</td>
|
||
|
<td align="left">multi</td>
|
||
|
<td align="left">Excel 2007+ XML Format</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>xlsm</code></td>
|
||
|
<td align="right"><code>.xlsm</code></td>
|
||
|
<td align="center">ZIP</td>
|
||
|
<td align="left">multi</td>
|
||
|
<td align="left">Excel 2007+ Macro XML Format</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>xlsb</code></td>
|
||
|
<td align="right"><code>.xlsb</code></td>
|
||
|
<td align="center">ZIP</td>
|
||
|
<td align="left">multi</td>
|
||
|
<td align="left">Excel 2007+ Binary Format</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>biff8</code></td>
|
||
|
<td align="right"><code>.xls</code></td>
|
||
|
<td align="center">CFB</td>
|
||
|
<td align="left">multi</td>
|
||
|
<td align="left">Excel 97-2004 Workbook Format</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>biff5</code></td>
|
||
|
<td align="right"><code>.xls</code></td>
|
||
|
<td align="center">CFB</td>
|
||
|
<td align="left">multi</td>
|
||
|
<td align="left">Excel 5.0/95 Workbook Format</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>biff2</code></td>
|
||
|
<td align="right"><code>.xls</code></td>
|
||
|
<td align="center">none</td>
|
||
|
<td align="left">single</td>
|
||
|
<td align="left">Excel 2.0 Worksheet Format</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>xlml</code></td>
|
||
|
<td align="right"><code>.xls</code></td>
|
||
|
<td align="center">none</td>
|
||
|
<td align="left">multi</td>
|
||
|
<td align="left">Excel 2003-2004 (SpreadsheetML)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>ods</code></td>
|
||
|
<td align="right"><code>.ods</code></td>
|
||
|
<td align="center">ZIP</td>
|
||
|
<td align="left">multi</td>
|
||
|
<td align="left">OpenDocument Spreadsheet</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>fods</code></td>
|
||
|
<td align="right"><code>.fods</code></td>
|
||
|
<td align="center">none</td>
|
||
|
<td align="left">multi</td>
|
||
|
<td align="left">Flat OpenDocument Spreadsheet</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>csv</code></td>
|
||
|
<td align="right"><code>.csv</code></td>
|
||
|
<td align="center">none</td>
|
||
|
<td align="left">single</td>
|
||
|
<td align="left">Comma Separated Values</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>txt</code></td>
|
||
|
<td align="right"><code>.txt</code></td>
|
||
|
<td align="center">none</td>
|
||
|
<td align="left">single</td>
|
||
|
<td align="left">UTF-16 Unicode Text (TXT)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>sylk</code></td>
|
||
|
<td align="right"><code>.sylk</code></td>
|
||
|
<td align="center">none</td>
|
||
|
<td align="left">single</td>
|
||
|
<td align="left">Symbolic Link (SYLK)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>html</code></td>
|
||
|
<td align="right"><code>.html</code></td>
|
||
|
<td align="center">none</td>
|
||
|
<td align="left">single</td>
|
||
|
<td align="left">HTML Document</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>dif</code></td>
|
||
|
<td align="right"><code>.dif</code></td>
|
||
|
<td align="center">none</td>
|
||
|
<td align="left">single</td>
|
||
|
<td align="left">Data Interchange Format (DIF)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>dbf</code></td>
|
||
|
<td align="right"><code>.dbf</code></td>
|
||
|
<td align="center">none</td>
|
||
|
<td align="left">single</td>
|
||
|
<td align="left">dBASE II + VFP Extensions (DBF)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>rtf</code></td>
|
||
|
<td align="right"><code>.rtf</code></td>
|
||
|
<td align="center">none</td>
|
||
|
<td align="left">single</td>
|
||
|
<td align="left">Rich Text Format (RTF)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>prn</code></td>
|
||
|
<td align="right"><code>.prn</code></td>
|
||
|
<td align="center">none</td>
|
||
|
<td align="left">single</td>
|
||
|
<td align="left">Lotus Formatted Text</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>eth</code></td>
|
||
|
<td align="right"><code>.eth</code></td>
|
||
|
<td align="center">none</td>
|
||
|
<td align="left">single</td>
|
||
|
<td align="left">Ethercalc Record Format (ETH)</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<ul>
|
||
|
<li>
|
||
|
<code>compression</code> only applies to formats with ZIP containers.</li>
|
||
|
<li>Formats that only support a single sheet require a <code>sheet</code> option specifying
|
||
|
the worksheet. If the string is empty, the first worksheet is used.</li>
|
||
|
<li>
|
||
|
<code>writeFile</code> will automatically guess the output file format based on the file
|
||
|
extension if <code>bookType</code> is not specified. It will choose the first format in
|
||
|
the aforementioned table that matches the extension.</li>
|
||
|
</ul>
|
||
|
<h3>
|
||
|
<a id="user-content-output-type" class="anchor" href="#output-type" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Output Type</h3>
|
||
|
<p>The <code>type</code> argument for <code>write</code> mirrors the <code>type</code> argument for <code>read</code>:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th><code>type</code></th>
|
||
|
<th>output</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td><code>"base64"</code></td>
|
||
|
<td>string: Base64 encoding of the file</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>"binary"</code></td>
|
||
|
<td>string: binary string (byte <code>n</code> is <code>data.charCodeAt(n)</code>)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>"string"</code></td>
|
||
|
<td>string: JS string (characters interpreted as UTF8)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>"buffer"</code></td>
|
||
|
<td>nodejs Buffer</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>"array"</code></td>
|
||
|
<td>ArrayBuffer, fallback array of 8-bit unsigned int</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><code>"file"</code></td>
|
||
|
<td>string: path of file that will be created (nodejs only)</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<h2>
|
||
|
<a id="user-content-utility-functions" class="anchor" href="#utility-functions" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Utility Functions</h2>
|
||
|
<p>The <code>sheet_to_*</code> functions accept a worksheet and an optional options object.</p>
|
||
|
<p>The <code>*_to_sheet</code> functions accept a data object and an optional options object.</p>
|
||
|
<p>The examples are based on the following worksheet:</p>
|
||
|
<pre><code>XXX| A | B | C | D | E | F | G |
|
||
|
---+---+---+---+---+---+---+---+
|
||
|
1 | S | h | e | e | t | J | S |
|
||
|
2 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|
||
|
3 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
||
|
</code></pre>
|
||
|
<h3>
|
||
|
<a id="user-content-array-of-arrays-input" class="anchor" href="#array-of-arrays-input" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Array of Arrays Input</h3>
|
||
|
<p><code>XLSX.utils.aoa_to_sheet</code> takes an array of arrays of JS values and returns a
|
||
|
worksheet resembling the input data. Numbers, Booleans and Strings are stored
|
||
|
as the corresponding styles. Dates are stored as date or numbers. Array holes
|
||
|
and explicit <code>undefined</code> values are skipped. <code>null</code> values may be stubbed. All
|
||
|
other values are stored as strings. The function takes an options argument:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left">Option Name</th>
|
||
|
<th align="center">Default</th>
|
||
|
<th align="left">Description</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left"><code>dateNF</code></td>
|
||
|
<td align="center">FMT 14</td>
|
||
|
<td align="left">Use specified date format in string output</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>cellDates</code></td>
|
||
|
<td align="center">false</td>
|
||
|
<td align="left">Store dates as type <code>d</code> (default is <code>n</code>)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>sheetStubs</code></td>
|
||
|
<td align="center">false</td>
|
||
|
<td align="left">Create cell objects of type <code>z</code> for <code>null</code> values</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<details>
|
||
|
<summary><b>Examples</b> (click to show)</summary>
|
||
|
<p>To generate the example sheet:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> ws <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">aoa_to_sheet</span>([
|
||
|
<span class="pl-s"><span class="pl-pds">"</span>SheetJS<span class="pl-pds">"</span></span>.<span class="pl-c1">split</span>(<span class="pl-s"><span class="pl-pds">"</span><span class="pl-pds">"</span></span>),
|
||
|
[<span class="pl-c1">1</span>,<span class="pl-c1">2</span>,<span class="pl-c1">3</span>,<span class="pl-c1">4</span>,<span class="pl-c1">5</span>,<span class="pl-c1">6</span>,<span class="pl-c1">7</span>],
|
||
|
[<span class="pl-c1">2</span>,<span class="pl-c1">3</span>,<span class="pl-c1">4</span>,<span class="pl-c1">5</span>,<span class="pl-c1">6</span>,<span class="pl-c1">7</span>,<span class="pl-c1">8</span>]
|
||
|
]);</pre></div>
|
||
|
</details>
|
||
|
<p><code>XLSX.utils.sheet_add_aoa</code> takes an array of arrays of JS values and updates an
|
||
|
existing worksheet object. It follows the same process as <code>aoa_to_sheet</code> and
|
||
|
accepts an options argument:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left">Option Name</th>
|
||
|
<th align="center">Default</th>
|
||
|
<th align="left">Description</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left"><code>dateNF</code></td>
|
||
|
<td align="center">FMT 14</td>
|
||
|
<td align="left">Use specified date format in string output</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>cellDates</code></td>
|
||
|
<td align="center">false</td>
|
||
|
<td align="left">Store dates as type <code>d</code> (default is <code>n</code>)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>sheetStubs</code></td>
|
||
|
<td align="center">false</td>
|
||
|
<td align="left">Create cell objects of type <code>z</code> for <code>null</code> values</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>origin</code></td>
|
||
|
<td align="center"></td>
|
||
|
<td align="left">Use specified cell as starting point (see below)</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<p><code>origin</code> is expected to be one of:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left"><code>origin</code></th>
|
||
|
<th align="left">Description</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left">(cell object)</td>
|
||
|
<td align="left">Use specified cell (cell object)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">(string)</td>
|
||
|
<td align="left">Use specified cell (A1-style cell)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">(number >= 0)</td>
|
||
|
<td align="left">Start from the first column at specified row (0-indexed)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">-1</td>
|
||
|
<td align="left">Append to bottom of worksheet starting on first column</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">(default)</td>
|
||
|
<td align="left">Start from cell A1</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<details>
|
||
|
<summary><b>Examples</b> (click to show)</summary>
|
||
|
<p>Consider the worksheet:</p>
|
||
|
<pre><code>XXX| A | B | C | D | E | F | G |
|
||
|
---+---+---+---+---+---+---+---+
|
||
|
1 | S | h | e | e | t | J | S |
|
||
|
2 | 1 | 2 | | | 5 | 6 | 7 |
|
||
|
3 | 2 | 3 | | | 6 | 7 | 8 |
|
||
|
4 | 3 | 4 | | | 7 | 8 | 9 |
|
||
|
5 | 4 | 5 | 6 | 7 | 8 | 9 | 0 |
|
||
|
</code></pre>
|
||
|
<p>This worksheet can be built up in the order <code>A1:G1, A2:B4, E2:G4, A5:G5</code>:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">/*</span> Initial row <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-k">var</span> ws <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">aoa_to_sheet</span>([ <span class="pl-s"><span class="pl-pds">"</span>SheetJS<span class="pl-pds">"</span></span>.<span class="pl-c1">split</span>(<span class="pl-s"><span class="pl-pds">"</span><span class="pl-pds">"</span></span>) ]);
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> Write data starting at A2 <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">sheet_add_aoa</span>(ws, [[<span class="pl-c1">1</span>,<span class="pl-c1">2</span>], [<span class="pl-c1">2</span>,<span class="pl-c1">3</span>], [<span class="pl-c1">3</span>,<span class="pl-c1">4</span>]], {origin<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>A2<span class="pl-pds">"</span></span>});
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> Write data starting at E2 <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">sheet_add_aoa</span>(ws, [[<span class="pl-c1">5</span>,<span class="pl-c1">6</span>,<span class="pl-c1">7</span>], [<span class="pl-c1">6</span>,<span class="pl-c1">7</span>,<span class="pl-c1">8</span>], [<span class="pl-c1">7</span>,<span class="pl-c1">8</span>,<span class="pl-c1">9</span>]], {origin<span class="pl-k">:</span>{r<span class="pl-k">:</span><span class="pl-c1">1</span>, c<span class="pl-k">:</span><span class="pl-c1">4</span>}});
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> Append row <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">sheet_add_aoa</span>(ws, [[<span class="pl-c1">4</span>,<span class="pl-c1">5</span>,<span class="pl-c1">6</span>,<span class="pl-c1">7</span>,<span class="pl-c1">8</span>,<span class="pl-c1">9</span>,<span class="pl-c1">0</span>]], {origin<span class="pl-k">:</span> <span class="pl-k">-</span><span class="pl-c1">1</span>});</pre></div>
|
||
|
</details>
|
||
|
<h3>
|
||
|
<a id="user-content-array-of-objects-input" class="anchor" href="#array-of-objects-input" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Array of Objects Input</h3>
|
||
|
<p><code>XLSX.utils.json_to_sheet</code> takes an array of objects and returns a worksheet
|
||
|
with automatically-generated "headers" based on the keys of the objects. The
|
||
|
default column order is determined by the first appearance of the field using
|
||
|
<code>Object.keys</code>, but can be overridden using the options argument:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left">Option Name</th>
|
||
|
<th align="center">Default</th>
|
||
|
<th align="left">Description</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left"><code>header</code></td>
|
||
|
<td align="center"></td>
|
||
|
<td align="left">Use specified column order (default <code>Object.keys</code>)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>dateNF</code></td>
|
||
|
<td align="center">FMT 14</td>
|
||
|
<td align="left">Use specified date format in string output</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>cellDates</code></td>
|
||
|
<td align="center">false</td>
|
||
|
<td align="left">Store dates as type <code>d</code> (default is <code>n</code>)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>skipHeader</code></td>
|
||
|
<td align="center">false</td>
|
||
|
<td align="left">If true, do not include header row in output</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<details>
|
||
|
<summary><b>Examples</b> (click to show)</summary>
|
||
|
<p>The original sheet cannot be reproduced using plain objects since JS object keys
|
||
|
must be unique. After replacing the second <code>e</code> and <code>S</code> with <code>e_1</code> and <code>S_1</code>:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> ws <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">json_to_sheet</span>([
|
||
|
{ <span class="pl-c1">S</span><span class="pl-k">:</span><span class="pl-c1">1</span>, h<span class="pl-k">:</span><span class="pl-c1">2</span>, e<span class="pl-k">:</span><span class="pl-c1">3</span>, e_1<span class="pl-k">:</span><span class="pl-c1">4</span>, t<span class="pl-k">:</span><span class="pl-c1">5</span>, <span class="pl-c1">J</span><span class="pl-k">:</span><span class="pl-c1">6</span>, <span class="pl-c1">S_1</span><span class="pl-k">:</span><span class="pl-c1">7</span> },
|
||
|
{ <span class="pl-c1">S</span><span class="pl-k">:</span><span class="pl-c1">2</span>, h<span class="pl-k">:</span><span class="pl-c1">3</span>, e<span class="pl-k">:</span><span class="pl-c1">4</span>, e_1<span class="pl-k">:</span><span class="pl-c1">5</span>, t<span class="pl-k">:</span><span class="pl-c1">6</span>, <span class="pl-c1">J</span><span class="pl-k">:</span><span class="pl-c1">7</span>, <span class="pl-c1">S_1</span><span class="pl-k">:</span><span class="pl-c1">8</span> }
|
||
|
], {header<span class="pl-k">:</span>[<span class="pl-s"><span class="pl-pds">"</span>S<span class="pl-pds">"</span></span>,<span class="pl-s"><span class="pl-pds">"</span>h<span class="pl-pds">"</span></span>,<span class="pl-s"><span class="pl-pds">"</span>e<span class="pl-pds">"</span></span>,<span class="pl-s"><span class="pl-pds">"</span>e_1<span class="pl-pds">"</span></span>,<span class="pl-s"><span class="pl-pds">"</span>t<span class="pl-pds">"</span></span>,<span class="pl-s"><span class="pl-pds">"</span>J<span class="pl-pds">"</span></span>,<span class="pl-s"><span class="pl-pds">"</span>S_1<span class="pl-pds">"</span></span>]});</pre></div>
|
||
|
<p>Alternatively, the header row can be skipped:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> ws <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">json_to_sheet</span>([
|
||
|
{ <span class="pl-c1">A</span><span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>S<span class="pl-pds">"</span></span>, <span class="pl-c1">B</span><span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>h<span class="pl-pds">"</span></span>, <span class="pl-c1">C</span><span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>e<span class="pl-pds">"</span></span>, <span class="pl-c1">D</span><span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>e<span class="pl-pds">"</span></span>, <span class="pl-c1">E</span><span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>t<span class="pl-pds">"</span></span>, <span class="pl-c1">F</span><span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>J<span class="pl-pds">"</span></span>, <span class="pl-c1">G</span><span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>S<span class="pl-pds">"</span></span> },
|
||
|
{ <span class="pl-c1">A</span><span class="pl-k">:</span> <span class="pl-c1">1</span>, <span class="pl-c1">B</span><span class="pl-k">:</span> <span class="pl-c1">2</span>, <span class="pl-c1">C</span><span class="pl-k">:</span> <span class="pl-c1">3</span>, <span class="pl-c1">D</span><span class="pl-k">:</span> <span class="pl-c1">4</span>, <span class="pl-c1">E</span><span class="pl-k">:</span> <span class="pl-c1">5</span>, <span class="pl-c1">F</span><span class="pl-k">:</span> <span class="pl-c1">6</span>, <span class="pl-c1">G</span><span class="pl-k">:</span> <span class="pl-c1">7</span> },
|
||
|
{ <span class="pl-c1">A</span><span class="pl-k">:</span> <span class="pl-c1">2</span>, <span class="pl-c1">B</span><span class="pl-k">:</span> <span class="pl-c1">3</span>, <span class="pl-c1">C</span><span class="pl-k">:</span> <span class="pl-c1">4</span>, <span class="pl-c1">D</span><span class="pl-k">:</span> <span class="pl-c1">5</span>, <span class="pl-c1">E</span><span class="pl-k">:</span> <span class="pl-c1">6</span>, <span class="pl-c1">F</span><span class="pl-k">:</span> <span class="pl-c1">7</span>, <span class="pl-c1">G</span><span class="pl-k">:</span> <span class="pl-c1">8</span> }
|
||
|
], {header<span class="pl-k">:</span>[<span class="pl-s"><span class="pl-pds">"</span>A<span class="pl-pds">"</span></span>,<span class="pl-s"><span class="pl-pds">"</span>B<span class="pl-pds">"</span></span>,<span class="pl-s"><span class="pl-pds">"</span>C<span class="pl-pds">"</span></span>,<span class="pl-s"><span class="pl-pds">"</span>D<span class="pl-pds">"</span></span>,<span class="pl-s"><span class="pl-pds">"</span>E<span class="pl-pds">"</span></span>,<span class="pl-s"><span class="pl-pds">"</span>F<span class="pl-pds">"</span></span>,<span class="pl-s"><span class="pl-pds">"</span>G<span class="pl-pds">"</span></span>], skipHeader<span class="pl-k">:</span><span class="pl-c1">true</span>});</pre></div>
|
||
|
</details>
|
||
|
<p><code>XLSX.utils.sheet_add_json</code> takes an array of objects and updates an existing
|
||
|
worksheet object. It follows the same process as <code>json_to_sheet</code> and accepts
|
||
|
an options argument:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left">Option Name</th>
|
||
|
<th align="center">Default</th>
|
||
|
<th align="left">Description</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left"><code>header</code></td>
|
||
|
<td align="center"></td>
|
||
|
<td align="left">Use specified column order (default <code>Object.keys</code>)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>dateNF</code></td>
|
||
|
<td align="center">FMT 14</td>
|
||
|
<td align="left">Use specified date format in string output</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>cellDates</code></td>
|
||
|
<td align="center">false</td>
|
||
|
<td align="left">Store dates as type <code>d</code> (default is <code>n</code>)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>skipHeader</code></td>
|
||
|
<td align="center">false</td>
|
||
|
<td align="left">If true, do not include header row in output</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>origin</code></td>
|
||
|
<td align="center"></td>
|
||
|
<td align="left">Use specified cell as starting point (see below)</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<p><code>origin</code> is expected to be one of:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left"><code>origin</code></th>
|
||
|
<th align="left">Description</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left">(cell object)</td>
|
||
|
<td align="left">Use specified cell (cell object)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">(string)</td>
|
||
|
<td align="left">Use specified cell (A1-style cell)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">(number >= 0)</td>
|
||
|
<td align="left">Start from the first column at specified row (0-indexed)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">-1</td>
|
||
|
<td align="left">Append to bottom of worksheet starting on first column</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">(default)</td>
|
||
|
<td align="left">Start from cell A1</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<details>
|
||
|
<summary><b>Examples</b> (click to show)</summary>
|
||
|
<p>Consider the worksheet:</p>
|
||
|
<pre><code>XXX| A | B | C | D | E | F | G |
|
||
|
---+---+---+---+---+---+---+---+
|
||
|
1 | S | h | e | e | t | J | S |
|
||
|
2 | 1 | 2 | | | 5 | 6 | 7 |
|
||
|
3 | 2 | 3 | | | 6 | 7 | 8 |
|
||
|
4 | 3 | 4 | | | 7 | 8 | 9 |
|
||
|
5 | 4 | 5 | 6 | 7 | 8 | 9 | 0 |
|
||
|
</code></pre>
|
||
|
<p>This worksheet can be built up in the order <code>A1:G1, A2:B4, E2:G4, A5:G5</code>:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-c"><span class="pl-c">/*</span> Initial row <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-k">var</span> ws <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">json_to_sheet</span>([
|
||
|
{ <span class="pl-c1">A</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>S<span class="pl-pds">"</span></span>, <span class="pl-c1">B</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>h<span class="pl-pds">"</span></span>, <span class="pl-c1">C</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>e<span class="pl-pds">"</span></span>, <span class="pl-c1">D</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>e<span class="pl-pds">"</span></span>, <span class="pl-c1">E</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>t<span class="pl-pds">"</span></span>, <span class="pl-c1">F</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>J<span class="pl-pds">"</span></span>, <span class="pl-c1">G</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>S<span class="pl-pds">"</span></span> }
|
||
|
], {header<span class="pl-k">:</span> [<span class="pl-s"><span class="pl-pds">"</span>A<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>B<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>C<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>D<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>E<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>F<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>G<span class="pl-pds">"</span></span>], skipHeader<span class="pl-k">:</span> <span class="pl-c1">true</span>});
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> Write data starting at A2 <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">sheet_add_json</span>(ws, [
|
||
|
{ <span class="pl-c1">A</span><span class="pl-k">:</span> <span class="pl-c1">1</span>, <span class="pl-c1">B</span><span class="pl-k">:</span> <span class="pl-c1">2</span> }, { <span class="pl-c1">A</span><span class="pl-k">:</span> <span class="pl-c1">2</span>, <span class="pl-c1">B</span><span class="pl-k">:</span> <span class="pl-c1">3</span> }, { <span class="pl-c1">A</span><span class="pl-k">:</span> <span class="pl-c1">3</span>, <span class="pl-c1">B</span><span class="pl-k">:</span> <span class="pl-c1">4</span> }
|
||
|
], {skipHeader<span class="pl-k">:</span> <span class="pl-c1">true</span>, origin<span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>A2<span class="pl-pds">"</span></span>});
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> Write data starting at E2 <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">sheet_add_json</span>(ws, [
|
||
|
{ <span class="pl-c1">A</span><span class="pl-k">:</span> <span class="pl-c1">5</span>, <span class="pl-c1">B</span><span class="pl-k">:</span> <span class="pl-c1">6</span>, <span class="pl-c1">C</span><span class="pl-k">:</span> <span class="pl-c1">7</span> }, { <span class="pl-c1">A</span><span class="pl-k">:</span> <span class="pl-c1">6</span>, <span class="pl-c1">B</span><span class="pl-k">:</span> <span class="pl-c1">7</span>, <span class="pl-c1">C</span><span class="pl-k">:</span> <span class="pl-c1">8</span> }, { <span class="pl-c1">A</span><span class="pl-k">:</span> <span class="pl-c1">7</span>, <span class="pl-c1">B</span><span class="pl-k">:</span> <span class="pl-c1">8</span>, <span class="pl-c1">C</span><span class="pl-k">:</span> <span class="pl-c1">9</span> }
|
||
|
], {skipHeader<span class="pl-k">:</span> <span class="pl-c1">true</span>, origin<span class="pl-k">:</span> { r<span class="pl-k">:</span> <span class="pl-c1">1</span>, c<span class="pl-k">:</span> <span class="pl-c1">4</span> }, header<span class="pl-k">:</span> [ <span class="pl-s"><span class="pl-pds">"</span>A<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>B<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>C<span class="pl-pds">"</span></span> ]});
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">/*</span> Append row <span class="pl-c">*/</span></span>
|
||
|
<span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">sheet_add_json</span>(ws, [
|
||
|
{ <span class="pl-c1">A</span><span class="pl-k">:</span> <span class="pl-c1">4</span>, <span class="pl-c1">B</span><span class="pl-k">:</span> <span class="pl-c1">5</span>, <span class="pl-c1">C</span><span class="pl-k">:</span> <span class="pl-c1">6</span>, <span class="pl-c1">D</span><span class="pl-k">:</span> <span class="pl-c1">7</span>, <span class="pl-c1">E</span><span class="pl-k">:</span> <span class="pl-c1">8</span>, <span class="pl-c1">F</span><span class="pl-k">:</span> <span class="pl-c1">9</span>, <span class="pl-c1">G</span><span class="pl-k">:</span> <span class="pl-c1">0</span> }
|
||
|
], {header<span class="pl-k">:</span> [<span class="pl-s"><span class="pl-pds">"</span>A<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>B<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>C<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>D<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>E<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>F<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>G<span class="pl-pds">"</span></span>], skipHeader<span class="pl-k">:</span> <span class="pl-c1">true</span>, origin<span class="pl-k">:</span> <span class="pl-k">-</span><span class="pl-c1">1</span>});</pre></div>
|
||
|
</details>
|
||
|
<h3>
|
||
|
<a id="user-content-html-table-input" class="anchor" href="#html-table-input" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>HTML Table Input</h3>
|
||
|
<p><code>XLSX.utils.table_to_sheet</code> takes a table DOM element and returns a worksheet
|
||
|
resembling the input table. Numbers are parsed. All other data will be stored
|
||
|
as strings.</p>
|
||
|
<p><code>XLSX.utils.table_to_book</code> produces a minimal workbook based on the worksheet.</p>
|
||
|
<p>Both functions accept options arguments:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left">Option Name</th>
|
||
|
<th align="center">Default</th>
|
||
|
<th align="left">Description</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left"><code>raw</code></td>
|
||
|
<td align="center"></td>
|
||
|
<td align="left">If true, every cell will hold raw strings</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>dateNF</code></td>
|
||
|
<td align="center">FMT 14</td>
|
||
|
<td align="left">Use specified date format in string output</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>cellDates</code></td>
|
||
|
<td align="center">false</td>
|
||
|
<td align="left">Store dates as type <code>d</code> (default is <code>n</code>)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>sheetRows</code></td>
|
||
|
<td align="center">0</td>
|
||
|
<td align="left">If >0, read the first <code>sheetRows</code> rows of the table</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>display</code></td>
|
||
|
<td align="center">false</td>
|
||
|
<td align="left">If true, hidden rows and cells will not be parsed</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<details>
|
||
|
<summary><b>Examples</b> (click to show)</summary>
|
||
|
<p>To generate the example sheet, start with the HTML table:</p>
|
||
|
<div class="highlight highlight-text-html-basic"><pre><<span class="pl-ent">table</span> <span class="pl-e">id</span>=<span class="pl-s"><span class="pl-pds">"</span>sheetjs<span class="pl-pds">"</span></span>>
|
||
|
<<span class="pl-ent">tr</span>><<span class="pl-ent">td</span>>S</<span class="pl-ent">td</span>><<span class="pl-ent">td</span>>h</<span class="pl-ent">td</span>><<span class="pl-ent">td</span>>e</<span class="pl-ent">td</span>><<span class="pl-ent">td</span>>e</<span class="pl-ent">td</span>><<span class="pl-ent">td</span>>t</<span class="pl-ent">td</span>><<span class="pl-ent">td</span>>J</<span class="pl-ent">td</span>><<span class="pl-ent">td</span>>S</<span class="pl-ent">td</span>></<span class="pl-ent">tr</span>>
|
||
|
<<span class="pl-ent">tr</span>><<span class="pl-ent">td</span>>1</<span class="pl-ent">td</span>><<span class="pl-ent">td</span>>2</<span class="pl-ent">td</span>><<span class="pl-ent">td</span>>3</<span class="pl-ent">td</span>><<span class="pl-ent">td</span>>4</<span class="pl-ent">td</span>><<span class="pl-ent">td</span>>5</<span class="pl-ent">td</span>><<span class="pl-ent">td</span>>6</<span class="pl-ent">td</span>><<span class="pl-ent">td</span>>7</<span class="pl-ent">td</span>></<span class="pl-ent">tr</span>>
|
||
|
<<span class="pl-ent">tr</span>><<span class="pl-ent">td</span>>2</<span class="pl-ent">td</span>><<span class="pl-ent">td</span>>3</<span class="pl-ent">td</span>><<span class="pl-ent">td</span>>4</<span class="pl-ent">td</span>><<span class="pl-ent">td</span>>5</<span class="pl-ent">td</span>><<span class="pl-ent">td</span>>6</<span class="pl-ent">td</span>><<span class="pl-ent">td</span>>7</<span class="pl-ent">td</span>><<span class="pl-ent">td</span>>8</<span class="pl-ent">td</span>></<span class="pl-ent">tr</span>>
|
||
|
</<span class="pl-ent">table</span>></pre></div>
|
||
|
<p>To process the table:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">var</span> tbl <span class="pl-k">=</span> <span class="pl-c1">document</span>.<span class="pl-c1">getElementById</span>(<span class="pl-s"><span class="pl-pds">'</span>sheetjs<span class="pl-pds">'</span></span>);
|
||
|
<span class="pl-k">var</span> wb <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">table_to_book</span>(tbl);</pre></div>
|
||
|
</details>
|
||
|
<p>Note: <code>XLSX.read</code> can handle HTML represented as strings.</p>
|
||
|
<h3>
|
||
|
<a id="user-content-formulae-output" class="anchor" href="#formulae-output" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Formulae Output</h3>
|
||
|
<p><code>XLSX.utils.sheet_to_formulae</code> generates an array of commands that represent
|
||
|
how a person would enter data into an application. Each entry is of the form
|
||
|
<code>A1-cell-address=formula-or-value</code>. String literals are prefixed with a <code>'</code> in
|
||
|
accordance with Excel.</p>
|
||
|
<details>
|
||
|
<summary><b>Examples</b> (click to show)</summary>
|
||
|
<p>For the example sheet:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">></span> <span class="pl-k">var</span> o <span class="pl-k">=</span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">sheet_to_formulae</span>(ws);
|
||
|
<span class="pl-k">></span> [o[<span class="pl-c1">0</span>], o[<span class="pl-c1">5</span>], o[<span class="pl-c1">10</span>], o[<span class="pl-c1">15</span>], o[<span class="pl-c1">20</span>]];
|
||
|
[ <span class="pl-s"><span class="pl-pds">'</span>A1=<span class="pl-cce">\'</span>S<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>F1=<span class="pl-cce">\'</span>J<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>D2=4<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>B3=3<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>G3=8<span class="pl-pds">'</span></span> ]</pre></div>
|
||
|
</details>
|
||
|
<h3>
|
||
|
<a id="user-content-delimiter-separated-output" class="anchor" href="#delimiter-separated-output" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Delimiter-Separated Output</h3>
|
||
|
<p>As an alternative to the <code>writeFile</code> CSV type, <code>XLSX.utils.sheet_to_csv</code> also
|
||
|
produces CSV output. The function takes an options argument:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left">Option Name</th>
|
||
|
<th align="center">Default</th>
|
||
|
<th align="left">Description</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left"><code>FS</code></td>
|
||
|
<td align="center"><code>","</code></td>
|
||
|
<td align="left">"Field Separator" delimiter between fields</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>RS</code></td>
|
||
|
<td align="center"><code>"\n"</code></td>
|
||
|
<td align="left">"Record Separator" delimiter between rows</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>dateNF</code></td>
|
||
|
<td align="center">FMT 14</td>
|
||
|
<td align="left">Use specified date format in string output</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>strip</code></td>
|
||
|
<td align="center">false</td>
|
||
|
<td align="left">Remove trailing field separators in each record **</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>blankrows</code></td>
|
||
|
<td align="center">true</td>
|
||
|
<td align="left">Include blank lines in the CSV output</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>skipHidden</code></td>
|
||
|
<td align="center">false</td>
|
||
|
<td align="left">Skips hidden rows/columns in the CSV output</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<ul>
|
||
|
<li>
|
||
|
<code>strip</code> will remove trailing commas from each line under default <code>FS/RS</code>
|
||
|
</li>
|
||
|
<li>
|
||
|
<code>blankrows</code> must be set to <code>false</code> to skip blank lines.</li>
|
||
|
</ul>
|
||
|
<details>
|
||
|
<summary><b>Examples</b> (click to show)</summary>
|
||
|
<p>For the example sheet:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">></span> <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">sheet_to_csv</span>(ws));
|
||
|
<span class="pl-c1">S</span>,h,e,e,t,<span class="pl-c1">J</span>,<span class="pl-c1">S</span>
|
||
|
<span class="pl-c1">1</span>,<span class="pl-c1">2</span>,<span class="pl-c1">3</span>,<span class="pl-c1">4</span>,<span class="pl-c1">5</span>,<span class="pl-c1">6</span>,<span class="pl-c1">7</span>
|
||
|
<span class="pl-c1">2</span>,<span class="pl-c1">3</span>,<span class="pl-c1">4</span>,<span class="pl-c1">5</span>,<span class="pl-c1">6</span>,<span class="pl-c1">7</span>,<span class="pl-c1">8</span>
|
||
|
<span class="pl-k">></span> <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">sheet_to_csv</span>(ws, {<span class="pl-c1">FS</span><span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span><span class="pl-cce">\t</span><span class="pl-pds">"</span></span>}));
|
||
|
<span class="pl-c1">S</span> h e e t <span class="pl-c1">J</span> <span class="pl-c1">S</span>
|
||
|
<span class="pl-c1">1</span> <span class="pl-c1">2</span> <span class="pl-c1">3</span> <span class="pl-c1">4</span> <span class="pl-c1">5</span> <span class="pl-c1">6</span> <span class="pl-c1">7</span>
|
||
|
<span class="pl-c1">2</span> <span class="pl-c1">3</span> <span class="pl-c1">4</span> <span class="pl-c1">5</span> <span class="pl-c1">6</span> <span class="pl-c1">7</span> <span class="pl-c1">8</span>
|
||
|
<span class="pl-k">></span> <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">sheet_to_csv</span>(ws,{<span class="pl-c1">FS</span><span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>:<span class="pl-pds">"</span></span>,<span class="pl-c1">RS</span><span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>|<span class="pl-pds">"</span></span>}));
|
||
|
<span class="pl-c1">S</span><span class="pl-k">:</span>h<span class="pl-k">:</span>e<span class="pl-k">:</span>e<span class="pl-k">:</span>t<span class="pl-k">:</span><span class="pl-c1">J</span><span class="pl-k">:</span><span class="pl-c1">S</span><span class="pl-k">|</span><span class="pl-c1">1</span><span class="pl-k">:</span><span class="pl-c1">2</span><span class="pl-k">:</span><span class="pl-c1">3</span><span class="pl-k">:</span><span class="pl-c1">4</span><span class="pl-k">:</span><span class="pl-c1">5</span><span class="pl-k">:</span><span class="pl-c1">6</span><span class="pl-k">:</span><span class="pl-c1">7</span><span class="pl-k">|</span><span class="pl-c1">2</span><span class="pl-k">:</span><span class="pl-c1">3</span><span class="pl-k">:</span><span class="pl-c1">4</span><span class="pl-k">:</span><span class="pl-c1">5</span><span class="pl-k">:</span><span class="pl-c1">6</span><span class="pl-k">:</span><span class="pl-c1">7</span><span class="pl-k">:</span><span class="pl-c1">8</span><span class="pl-k">|</span></pre></div>
|
||
|
</details>
|
||
|
<h4>
|
||
|
<a id="user-content-utf-16-unicode-text" class="anchor" href="#utf-16-unicode-text" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>UTF-16 Unicode Text</h4>
|
||
|
<p>The <code>txt</code> output type uses the tab character as the field separator. If the
|
||
|
<code>codepage</code> library is available (included in full distribution but not core),
|
||
|
the output will be encoded in <code>CP1200</code> and the BOM will be prepended.</p>
|
||
|
<p><code>XLSX.utils.sheet_to_txt</code> takes the same arguments as <code>sheet_to_csv</code>.</p>
|
||
|
<h3>
|
||
|
<a id="user-content-html-output" class="anchor" href="#html-output" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>HTML Output</h3>
|
||
|
<p>As an alternative to the <code>writeFile</code> HTML type, <code>XLSX.utils.sheet_to_html</code> also
|
||
|
produces HTML output. The function takes an options argument:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left">Option Name</th>
|
||
|
<th align="center">Default</th>
|
||
|
<th align="left">Description</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left"><code>id</code></td>
|
||
|
<td align="center"></td>
|
||
|
<td align="left">Specify the <code>id</code> attribute for the <code>TABLE</code> element</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>editable</code></td>
|
||
|
<td align="center">false</td>
|
||
|
<td align="left">If true, set <code>contenteditable="true"</code> for every TD</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>header</code></td>
|
||
|
<td align="center"></td>
|
||
|
<td align="left">Override header (default <code>html body</code>)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>footer</code></td>
|
||
|
<td align="center"></td>
|
||
|
<td align="left">Override footer (default <code>/body /html</code>)</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<details>
|
||
|
<summary><b>Examples</b> (click to show)</summary>
|
||
|
<p>For the example sheet:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">></span> <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">sheet_to_html</span>(ws));
|
||
|
<span class="pl-c"><span class="pl-c">//</span> ...</span></pre></div>
|
||
|
</details>
|
||
|
<h3>
|
||
|
<a id="user-content-json" class="anchor" href="#json" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>JSON</h3>
|
||
|
<p><code>XLSX.utils.sheet_to_json</code> generates different types of JS objects. The function
|
||
|
takes an options argument:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left">Option Name</th>
|
||
|
<th align="center">Default</th>
|
||
|
<th align="left">Description</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left"><code>raw</code></td>
|
||
|
<td align="center"><code>true</code></td>
|
||
|
<td align="left">Use raw values (true) or formatted strings (false)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>range</code></td>
|
||
|
<td align="center">from WS</td>
|
||
|
<td align="left">Override Range (see table below)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>header</code></td>
|
||
|
<td align="center"></td>
|
||
|
<td align="left">Control output format (see table below)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>dateNF</code></td>
|
||
|
<td align="center">FMT 14</td>
|
||
|
<td align="left">Use specified date format in string output</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>defval</code></td>
|
||
|
<td align="center"></td>
|
||
|
<td align="left">Use specified value in place of null or undefined</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>blankrows</code></td>
|
||
|
<td align="center">**</td>
|
||
|
<td align="left">Include blank lines in the output **</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<ul>
|
||
|
<li>
|
||
|
<code>raw</code> only affects cells which have a format code (<code>.z</code>) field or a formatted
|
||
|
text (<code>.w</code>) field.</li>
|
||
|
<li>If <code>header</code> is specified, the first row is considered a data row; if <code>header</code>
|
||
|
is not specified, the first row is the header row and not considered data.</li>
|
||
|
<li>When <code>header</code> is not specified, the conversion will automatically disambiguate
|
||
|
header entries by affixing <code>_</code> and a count starting at <code>1</code>. For example, if
|
||
|
three columns have header <code>foo</code> the output fields are <code>foo</code>, <code>foo_1</code>, <code>foo_2</code>
|
||
|
</li>
|
||
|
<li>
|
||
|
<code>null</code> values are returned when <code>raw</code> is true but are skipped when false.</li>
|
||
|
<li>If <code>defval</code> is not specified, null and undefined values are skipped normally.
|
||
|
If specified, all null and undefined points will be filled with <code>defval</code>
|
||
|
</li>
|
||
|
<li>When <code>header</code> is <code>1</code>, the default is to generate blank rows. <code>blankrows</code> must
|
||
|
be set to <code>false</code> to skip blank rows.</li>
|
||
|
<li>When <code>header</code> is not <code>1</code>, the default is to skip blank rows. <code>blankrows</code> must
|
||
|
be true to generate blank rows</li>
|
||
|
</ul>
|
||
|
<p><code>range</code> is expected to be one of:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left"><code>range</code></th>
|
||
|
<th align="left">Description</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left">(number)</td>
|
||
|
<td align="left">Use worksheet range but set starting row to the value</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">(string)</td>
|
||
|
<td align="left">Use specified range (A1-style bounded range string)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">(default)</td>
|
||
|
<td align="left">Use worksheet range (<code>ws['!ref']</code>)</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<p><code>header</code> is expected to be one of:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left"><code>header</code></th>
|
||
|
<th align="left">Description</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left"><code>1</code></td>
|
||
|
<td align="left">Generate an array of arrays ("2D Array")</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>"A"</code></td>
|
||
|
<td align="left">Row object keys are literal column labels</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">array of strings</td>
|
||
|
<td align="left">Use specified strings as keys in row objects</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">(default)</td>
|
||
|
<td align="left">Read and disambiguate first row as keys</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<p>If header is not <code>1</code>, the row object will contain the non-enumerable property
|
||
|
<code>__rowNum__</code> that represents the row of the sheet corresponding to the entry.</p>
|
||
|
<details>
|
||
|
<summary><b>Examples</b> (click to show)</summary>
|
||
|
<p>For the example sheet:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">></span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">sheet_to_json</span>(ws);
|
||
|
[ { <span class="pl-c1">S</span><span class="pl-k">:</span> <span class="pl-c1">1</span>, h<span class="pl-k">:</span> <span class="pl-c1">2</span>, e<span class="pl-k">:</span> <span class="pl-c1">3</span>, e_1<span class="pl-k">:</span> <span class="pl-c1">4</span>, t<span class="pl-k">:</span> <span class="pl-c1">5</span>, <span class="pl-c1">J</span><span class="pl-k">:</span> <span class="pl-c1">6</span>, <span class="pl-c1">S_1</span><span class="pl-k">:</span> <span class="pl-c1">7</span> },
|
||
|
{ <span class="pl-c1">S</span><span class="pl-k">:</span> <span class="pl-c1">2</span>, h<span class="pl-k">:</span> <span class="pl-c1">3</span>, e<span class="pl-k">:</span> <span class="pl-c1">4</span>, e_1<span class="pl-k">:</span> <span class="pl-c1">5</span>, t<span class="pl-k">:</span> <span class="pl-c1">6</span>, <span class="pl-c1">J</span><span class="pl-k">:</span> <span class="pl-c1">7</span>, <span class="pl-c1">S_1</span><span class="pl-k">:</span> <span class="pl-c1">8</span> } ]
|
||
|
|
||
|
<span class="pl-k">></span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">sheet_to_json</span>(ws, {header<span class="pl-k">:</span><span class="pl-s"><span class="pl-pds">"</span>A<span class="pl-pds">"</span></span>});
|
||
|
[ { <span class="pl-c1">A</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>S<span class="pl-pds">'</span></span>, <span class="pl-c1">B</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>h<span class="pl-pds">'</span></span>, <span class="pl-c1">C</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>e<span class="pl-pds">'</span></span>, <span class="pl-c1">D</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>e<span class="pl-pds">'</span></span>, <span class="pl-c1">E</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>t<span class="pl-pds">'</span></span>, <span class="pl-c1">F</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>J<span class="pl-pds">'</span></span>, <span class="pl-c1">G</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>S<span class="pl-pds">'</span></span> },
|
||
|
{ <span class="pl-c1">A</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>1<span class="pl-pds">'</span></span>, <span class="pl-c1">B</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>2<span class="pl-pds">'</span></span>, <span class="pl-c1">C</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>3<span class="pl-pds">'</span></span>, <span class="pl-c1">D</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>4<span class="pl-pds">'</span></span>, <span class="pl-c1">E</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>5<span class="pl-pds">'</span></span>, <span class="pl-c1">F</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>6<span class="pl-pds">'</span></span>, <span class="pl-c1">G</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>7<span class="pl-pds">'</span></span> },
|
||
|
{ <span class="pl-c1">A</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>2<span class="pl-pds">'</span></span>, <span class="pl-c1">B</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>3<span class="pl-pds">'</span></span>, <span class="pl-c1">C</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>4<span class="pl-pds">'</span></span>, <span class="pl-c1">D</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>5<span class="pl-pds">'</span></span>, <span class="pl-c1">E</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>6<span class="pl-pds">'</span></span>, <span class="pl-c1">F</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>7<span class="pl-pds">'</span></span>, <span class="pl-c1">G</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>8<span class="pl-pds">'</span></span> } ]
|
||
|
|
||
|
<span class="pl-k">></span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">sheet_to_json</span>(ws, {header<span class="pl-k">:</span>[<span class="pl-s"><span class="pl-pds">"</span>A<span class="pl-pds">"</span></span>,<span class="pl-s"><span class="pl-pds">"</span>E<span class="pl-pds">"</span></span>,<span class="pl-s"><span class="pl-pds">"</span>I<span class="pl-pds">"</span></span>,<span class="pl-s"><span class="pl-pds">"</span>O<span class="pl-pds">"</span></span>,<span class="pl-s"><span class="pl-pds">"</span>U<span class="pl-pds">"</span></span>,<span class="pl-s"><span class="pl-pds">"</span>6<span class="pl-pds">"</span></span>,<span class="pl-s"><span class="pl-pds">"</span>9<span class="pl-pds">"</span></span>]});
|
||
|
[ { <span class="pl-s"><span class="pl-pds">'</span>6<span class="pl-pds">'</span></span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>J<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>9<span class="pl-pds">'</span></span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>S<span class="pl-pds">'</span></span>, <span class="pl-c1">A</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>S<span class="pl-pds">'</span></span>, <span class="pl-c1">E</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>h<span class="pl-pds">'</span></span>, <span class="pl-c1">I</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>e<span class="pl-pds">'</span></span>, <span class="pl-c1">O</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>e<span class="pl-pds">'</span></span>, <span class="pl-c1">U</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>t<span class="pl-pds">'</span></span> },
|
||
|
{ <span class="pl-s"><span class="pl-pds">'</span>6<span class="pl-pds">'</span></span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>6<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>9<span class="pl-pds">'</span></span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>7<span class="pl-pds">'</span></span>, <span class="pl-c1">A</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>1<span class="pl-pds">'</span></span>, <span class="pl-c1">E</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>2<span class="pl-pds">'</span></span>, <span class="pl-c1">I</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>3<span class="pl-pds">'</span></span>, <span class="pl-c1">O</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>4<span class="pl-pds">'</span></span>, <span class="pl-c1">U</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>5<span class="pl-pds">'</span></span> },
|
||
|
{ <span class="pl-s"><span class="pl-pds">'</span>6<span class="pl-pds">'</span></span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>7<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>9<span class="pl-pds">'</span></span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>8<span class="pl-pds">'</span></span>, <span class="pl-c1">A</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>2<span class="pl-pds">'</span></span>, <span class="pl-c1">E</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>3<span class="pl-pds">'</span></span>, <span class="pl-c1">I</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>4<span class="pl-pds">'</span></span>, <span class="pl-c1">O</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>5<span class="pl-pds">'</span></span>, <span class="pl-c1">U</span><span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">'</span>6<span class="pl-pds">'</span></span> } ]
|
||
|
|
||
|
<span class="pl-k">></span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">sheet_to_json</span>(ws, {header<span class="pl-k">:</span><span class="pl-c1">1</span>});
|
||
|
[ [ <span class="pl-s"><span class="pl-pds">'</span>S<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>h<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>e<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>e<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>t<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>J<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>S<span class="pl-pds">'</span></span> ],
|
||
|
[ <span class="pl-s"><span class="pl-pds">'</span>1<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>2<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>3<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>4<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>5<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>6<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>7<span class="pl-pds">'</span></span> ],
|
||
|
[ <span class="pl-s"><span class="pl-pds">'</span>2<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>3<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>4<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>5<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>6<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>7<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>8<span class="pl-pds">'</span></span> ] ]</pre></div>
|
||
|
<p>Example showing the effect of <code>raw</code>:</p>
|
||
|
<div class="highlight highlight-source-js"><pre><span class="pl-k">></span> ws[<span class="pl-s"><span class="pl-pds">'</span>A2<span class="pl-pds">'</span></span>].<span class="pl-smi">w</span> <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">"</span>3<span class="pl-pds">"</span></span>; <span class="pl-c"><span class="pl-c">//</span> set A2 formatted string value</span>
|
||
|
|
||
|
<span class="pl-k">></span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">sheet_to_json</span>(ws, {header<span class="pl-k">:</span><span class="pl-c1">1</span>, raw<span class="pl-k">:</span><span class="pl-c1">false</span>});
|
||
|
[ [ <span class="pl-s"><span class="pl-pds">'</span>S<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>h<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>e<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>e<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>t<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>J<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>S<span class="pl-pds">'</span></span> ],
|
||
|
[ <span class="pl-s"><span class="pl-pds">'</span>3<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>2<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>3<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>4<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>5<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>6<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>7<span class="pl-pds">'</span></span> ], <span class="pl-c"><span class="pl-c">//</span> <-- A2 uses the formatted string</span>
|
||
|
[ <span class="pl-s"><span class="pl-pds">'</span>2<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>3<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>4<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>5<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>6<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>7<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>8<span class="pl-pds">'</span></span> ] ]
|
||
|
|
||
|
<span class="pl-k">></span> <span class="pl-c1">XLSX</span>.<span class="pl-smi">utils</span>.<span class="pl-en">sheet_to_json</span>(ws, {header<span class="pl-k">:</span><span class="pl-c1">1</span>});
|
||
|
[ [ <span class="pl-s"><span class="pl-pds">'</span>S<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>h<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>e<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>e<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>t<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>J<span class="pl-pds">'</span></span>, <span class="pl-s"><span class="pl-pds">'</span>S<span class="pl-pds">'</span></span> ],
|
||
|
[ <span class="pl-c1">1</span>, <span class="pl-c1">2</span>, <span class="pl-c1">3</span>, <span class="pl-c1">4</span>, <span class="pl-c1">5</span>, <span class="pl-c1">6</span>, <span class="pl-c1">7</span> ], <span class="pl-c"><span class="pl-c">//</span> <-- A2 uses the raw value</span>
|
||
|
[ <span class="pl-c1">2</span>, <span class="pl-c1">3</span>, <span class="pl-c1">4</span>, <span class="pl-c1">5</span>, <span class="pl-c1">6</span>, <span class="pl-c1">7</span>, <span class="pl-c1">8</span> ] ]</pre></div>
|
||
|
</details>
|
||
|
<h2>
|
||
|
<a id="user-content-file-formats" class="anchor" href="#file-formats" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>File Formats</h2>
|
||
|
<p>Despite the library name <code>xlsx</code>, it supports numerous spreadsheet file formats:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left">Format</th>
|
||
|
<th align="center">Read</th>
|
||
|
<th align="center">Write</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left"><strong>Excel Worksheet/Workbook Formats</strong></td>
|
||
|
<td align="center">:-----:</td>
|
||
|
<td align="center">:-----:</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">Excel 2007+ XML Formats (XLSX/XLSM)</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">Excel 2007+ Binary Format (XLSB BIFF12)</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">Excel 2003-2004 XML Format (XML "SpreadsheetML")</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">Excel 97-2004 (XLS BIFF8)</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">Excel 5.0/95 (XLS BIFF5)</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">Excel 4.0 (XLS/XLW BIFF4)</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">Excel 3.0 (XLS BIFF3)</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">Excel 2.0/2.1 (XLS BIFF2)</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><strong>Excel Supported Text Formats</strong></td>
|
||
|
<td align="center">:-----:</td>
|
||
|
<td align="center">:-----:</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">Delimiter-Separated Values (CSV/TXT)</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">Data Interchange Format (DIF)</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">Symbolic Link (SYLK/SLK)</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">Lotus Formatted Text (PRN)</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">UTF-16 Unicode Text (TXT)</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><strong>Other Workbook/Worksheet Formats</strong></td>
|
||
|
<td align="center">:-----:</td>
|
||
|
<td align="center">:-----:</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">OpenDocument Spreadsheet (ODS)</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">Flat XML ODF Spreadsheet (FODS)</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">Uniform Office Format Spreadsheet (标文通 UOS1/UOS2)</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">dBASE II/III/IV / Visual FoxPro (DBF)</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">Lotus 1-2-3 (WKS/WK1/WK2/WK3/WK4/123)</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">Quattro Pro Spreadsheet (WQ1/WQ2/WB1/WB2/WB3/QPW)</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><strong>Other Common Spreadsheet Output Formats</strong></td>
|
||
|
<td align="center">:-----:</td>
|
||
|
<td align="center">:-----:</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">HTML Tables</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">Rich Text Format tables (RTF)</td>
|
||
|
<td align="center"></td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">Ethercalc Record Format (ETH)</td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
<td align="center"><g-emoji class="g-emoji" alias="o" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/2b55.png">⭕️</g-emoji></td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<p>Features not supported by a given file format will not be written. Formats with
|
||
|
range limits will be silently truncated:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left">Format</th>
|
||
|
<th align="left">Last Cell</th>
|
||
|
<th align="right">Max Cols</th>
|
||
|
<th align="right">Max Rows</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left">Excel 2007+ XML Formats (XLSX/XLSM)</td>
|
||
|
<td align="left">XFD1048576</td>
|
||
|
<td align="right">16384</td>
|
||
|
<td align="right">1048576</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">Excel 2007+ Binary Format (XLSB BIFF12)</td>
|
||
|
<td align="left">XFD1048576</td>
|
||
|
<td align="right">16384</td>
|
||
|
<td align="right">1048576</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">Excel 97-2004 (XLS BIFF8)</td>
|
||
|
<td align="left">IV65536</td>
|
||
|
<td align="right">256</td>
|
||
|
<td align="right">65536</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">Excel 5.0/95 (XLS BIFF5)</td>
|
||
|
<td align="left">IV16384</td>
|
||
|
<td align="right">256</td>
|
||
|
<td align="right">16384</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left">Excel 2.0/2.1 (XLS BIFF2)</td>
|
||
|
<td align="left">IV16384</td>
|
||
|
<td align="right">256</td>
|
||
|
<td align="right">16384</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
<p>Excel 2003 SpreadsheetML range limits are governed by the version of Excel and
|
||
|
are not enforced by the writer.</p>
|
||
|
<h3>
|
||
|
<a id="user-content-excel-2007-xml-xlsxxlsm" class="anchor" href="#excel-2007-xml-xlsxxlsm" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Excel 2007+ XML (XLSX/XLSM)</h3>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<p>XLSX and XLSM files are ZIP containers containing a series of XML files in
|
||
|
accordance with the Open Packaging Conventions (OPC). The XLSM format, almost
|
||
|
identical to XLSX, is used for files containing macros.</p>
|
||
|
<p>The format is standardized in ECMA-376 and later in ISO/IEC 29500. Excel does
|
||
|
not follow the specification, and there are additional documents discussing how
|
||
|
Excel deviates from the specification.</p>
|
||
|
</details>
|
||
|
<h3>
|
||
|
<a id="user-content-excel-20-95-biff2biff3biff4biff5" class="anchor" href="#excel-20-95-biff2biff3biff4biff5" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Excel 2.0-95 (BIFF2/BIFF3/BIFF4/BIFF5)</h3>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<p>BIFF 2/3 XLS are single-sheet streams of binary records. Excel 4 introduced
|
||
|
the concept of a workbook (<code>XLW</code> files) but also had single-sheet <code>XLS</code> format.
|
||
|
The structure is largely similar to the Lotus 1-2-3 file formats. BIFF5/8/12
|
||
|
extended the format in various ways but largely stuck to the same record format.</p>
|
||
|
<p>There is no official specification for any of these formats. Excel 95 can write
|
||
|
files in these formats, so record lengths and fields were determined by writing
|
||
|
in all of the supported formats and comparing files. Excel 2016 can generate
|
||
|
BIFF5 files, enabling a full suite of file tests starting from XLSX or BIFF2.</p>
|
||
|
</details>
|
||
|
<h3>
|
||
|
<a id="user-content-excel-97-2004-binary-biff8" class="anchor" href="#excel-97-2004-binary-biff8" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Excel 97-2004 Binary (BIFF8)</h3>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<p>BIFF8 exclusively uses the Compound File Binary container format, splitting some
|
||
|
content into streams within the file. At its core, it still uses an extended
|
||
|
version of the binary record format from older versions of BIFF.</p>
|
||
|
<p>The <code>MS-XLS</code> specification covers the basics of the file format, and other
|
||
|
specifications expand on serialization of features like properties.</p>
|
||
|
</details>
|
||
|
<h3>
|
||
|
<a id="user-content-excel-2003-2004-spreadsheetml" class="anchor" href="#excel-2003-2004-spreadsheetml" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Excel 2003-2004 (SpreadsheetML)</h3>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<p>Predating XLSX, SpreadsheetML files are simple XML files. There is no official
|
||
|
and comprehensive specification, although MS has released documentation on the
|
||
|
format. Since Excel 2016 can generate SpreadsheetML files, mapping features is
|
||
|
pretty straightforward.</p>
|
||
|
</details>
|
||
|
<h3>
|
||
|
<a id="user-content-excel-2007-binary-xlsb-biff12" class="anchor" href="#excel-2007-binary-xlsb-biff12" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Excel 2007+ Binary (XLSB, BIFF12)</h3>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<p>Introduced in parallel with XLSX, the XLSB format combines the BIFF architecture
|
||
|
with the content separation and ZIP container of XLSX. For the most part nodes
|
||
|
in an XLSX sub-file can be mapped to XLSB records in a corresponding sub-file.</p>
|
||
|
<p>The <code>MS-XLSB</code> specification covers the basics of the file format, and other
|
||
|
specifications expand on serialization of features like properties.</p>
|
||
|
</details>
|
||
|
<h3>
|
||
|
<a id="user-content-delimiter-separated-values-csvtxt" class="anchor" href="#delimiter-separated-values-csvtxt" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Delimiter-Separated Values (CSV/TXT)</h3>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<p>Excel CSV deviates from RFC4180 in a number of important ways. The generated
|
||
|
CSV files should generally work in Excel although they may not work in RFC4180
|
||
|
compatible readers. The parser should generally understand Excel CSV. The
|
||
|
writer proactively generates cells for formulae if values are unavailable.</p>
|
||
|
<p>Excel TXT uses tab as the delimiter and code page 1200.</p>
|
||
|
<p>Notes:</p>
|
||
|
<ul>
|
||
|
<li>Like in Excel, files starting with <code>0x49 0x44 ("ID")</code> are treated as Symbolic
|
||
|
Link files. Unlike Excel, if the file does not have a valid SYLK header, it
|
||
|
will be proactively reinterpreted as CSV. There are some files with semicolon
|
||
|
delimiter that align with a valid SYLK file. For the broadest compatibility,
|
||
|
all cells with the value of <code>ID</code> are automatically wrapped in double-quotes.</li>
|
||
|
</ul>
|
||
|
</details>
|
||
|
<h3>
|
||
|
<a id="user-content-other-workbook-formats" class="anchor" href="#other-workbook-formats" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Other Workbook Formats</h3>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<p>Support for other formats is generally far XLS/XLSB/XLSX support, due in large
|
||
|
part to a lack of publicly available documentation. Test files were produced in
|
||
|
the respective apps and compared to their XLS exports to determine structure.
|
||
|
The main focus is data extraction.</p>
|
||
|
</details>
|
||
|
<h4>
|
||
|
<a id="user-content-lotus-1-2-3-wkswk1wk2wk3wk4123" class="anchor" href="#lotus-1-2-3-wkswk1wk2wk3wk4123" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Lotus 1-2-3 (WKS/WK1/WK2/WK3/WK4/123)</h4>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<p>The Lotus formats consist of binary records similar to the BIFF structure. Lotus
|
||
|
did release a specification decades ago covering the original WK1 format. Other
|
||
|
features were deduced by producing files and comparing to Excel support.</p>
|
||
|
</details>
|
||
|
<h4>
|
||
|
<a id="user-content-quattro-pro-wq1wq2wb1wb2wb3qpw" class="anchor" href="#quattro-pro-wq1wq2wb1wb2wb3qpw" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Quattro Pro (WQ1/WQ2/WB1/WB2/WB3/QPW)</h4>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<p>The Quattro Pro formats use binary records in the same way as BIFF and Lotus.
|
||
|
Some of the newer formats (namely WB3 and QPW) use a CFB enclosure just like
|
||
|
BIFF8 XLS.</p>
|
||
|
</details>
|
||
|
<h4>
|
||
|
<a id="user-content-opendocument-spreadsheet-odsfods" class="anchor" href="#opendocument-spreadsheet-odsfods" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>OpenDocument Spreadsheet (ODS/FODS)</h4>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<p>ODS is an XML-in-ZIP format akin to XLSX while FODS is an XML format akin to
|
||
|
SpreadsheetML. Both are detailed in the OASIS standard, but tools like LO/OO
|
||
|
add undocumented extensions. The parsers and writers do not implement the full
|
||
|
standard, instead focusing on parts necessary to extract and store raw data.</p>
|
||
|
</details>
|
||
|
<h4>
|
||
|
<a id="user-content-uniform-office-spreadsheet-uos12" class="anchor" href="#uniform-office-spreadsheet-uos12" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Uniform Office Spreadsheet (UOS1/2)</h4>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<p>UOS is a very similar format, and it comes in 2 varieties corresponding to ODS
|
||
|
and FODS respectively. For the most part, the difference between the formats
|
||
|
is in the names of tags and attributes.</p>
|
||
|
</details>
|
||
|
<h3>
|
||
|
<a id="user-content-other-single-worksheet-formats" class="anchor" href="#other-single-worksheet-formats" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Other Single-Worksheet Formats</h3>
|
||
|
<p>Many older formats supported only one worksheet:</p>
|
||
|
<h4>
|
||
|
<a id="user-content-dbase-and-visual-foxpro-dbf" class="anchor" href="#dbase-and-visual-foxpro-dbf" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>dBASE and Visual FoxPro (DBF)</h4>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<p>DBF is really a typed table format: each column can only hold one data type and
|
||
|
each record omits type information. The parser generates a header row and
|
||
|
inserts records starting at the second row of the worksheet. The writer makes
|
||
|
files compatible with Visual FoxPro extensions.</p>
|
||
|
<p>Multi-file extensions like external memos and tables are currently unsupported,
|
||
|
limited by the general ability to read arbitrary files in the web browser. The
|
||
|
reader understands DBF Level 7 extensions like DATETIME.</p>
|
||
|
</details>
|
||
|
<h4>
|
||
|
<a id="user-content-symbolic-link-sylk" class="anchor" href="#symbolic-link-sylk" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Symbolic Link (SYLK)</h4>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<p>There is no real documentation. All knowledge was gathered by saving files in
|
||
|
various versions of Excel to deduce the meaning of fields. Notes:</p>
|
||
|
<ul>
|
||
|
<li>Plain formulae are stored in the RC form.</li>
|
||
|
<li>Column widths are rounded to integral characters.</li>
|
||
|
</ul>
|
||
|
</details>
|
||
|
<h4>
|
||
|
<a id="user-content-lotus-formatted-text-prn" class="anchor" href="#lotus-formatted-text-prn" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Lotus Formatted Text (PRN)</h4>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<p>There is no real documentation, and in fact Excel treats PRN as an output-only
|
||
|
file format. Nevertheless we can guess the column widths and reverse-engineer
|
||
|
the original layout. Excel's 240 character width limitation is not enforced.</p>
|
||
|
</details>
|
||
|
<h4>
|
||
|
<a id="user-content-data-interchange-format-dif" class="anchor" href="#data-interchange-format-dif" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Data Interchange Format (DIF)</h4>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<p>There is no unified definition. Visicalc DIF differs from Lotus DIF, and both
|
||
|
differ from Excel DIF. Where ambiguous, the parser/writer follows the expected
|
||
|
behavior from Excel. In particular, Excel extends DIF in incompatible ways:</p>
|
||
|
<ul>
|
||
|
<li>Since Excel automatically converts numbers-as-strings to numbers, numeric
|
||
|
string constants are converted to formulae: <code>"0.3" -> "=""0.3""</code>
|
||
|
</li>
|
||
|
<li>DIF technically expects numeric cells to hold the raw numeric data, but Excel
|
||
|
permits formatted numbers (including dates)</li>
|
||
|
<li>DIF technically has no support for formulae, but Excel will automatically
|
||
|
convert plain formulae. Array formulae are not preserved.</li>
|
||
|
</ul>
|
||
|
</details>
|
||
|
<h4>
|
||
|
<a id="user-content-html" class="anchor" href="#html" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>HTML</h4>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<p>Excel HTML worksheets include special metadata encoded in styles. For example,
|
||
|
<code>mso-number-format</code> is a localized string containing the number format. Despite
|
||
|
the metadata the output is valid HTML, although it does accept bare <code>&</code> symbols.</p>
|
||
|
<p>The writer adds type metadata to the TD elements via the <code>t</code> tag. The parser
|
||
|
looks for those tags and overrides the default interpretation. For example, text
|
||
|
like <code><td>12345</td></code> will be parsed as numbers but <code><td t="s">12345</td></code> will
|
||
|
be parsed as text.</p>
|
||
|
</details>
|
||
|
<h4>
|
||
|
<a id="user-content-rich-text-format-rtf" class="anchor" href="#rich-text-format-rtf" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Rich Text Format (RTF)</h4>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<p>Excel RTF worksheets are stored in clipboard when copying cells or ranges from a
|
||
|
worksheet. The supported codes are a subset of the Word RTF support.</p>
|
||
|
</details>
|
||
|
<h4>
|
||
|
<a id="user-content-ethercalc-record-format-eth" class="anchor" href="#ethercalc-record-format-eth" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Ethercalc Record Format (ETH)</h4>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<p><a href="https://ethercalc.net/" rel="nofollow">Ethercalc</a> is an open source web spreadsheet powered by
|
||
|
a record format reminiscent of SYLK wrapped in a MIME multi-part message.</p>
|
||
|
</details>
|
||
|
<h2>
|
||
|
<a id="user-content-testing" class="anchor" href="#testing" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Testing</h2>
|
||
|
<h3>
|
||
|
<a id="user-content-node" class="anchor" href="#node" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Node</h3>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<p><code>make test</code> will run the node-based tests. By default it runs tests on files in
|
||
|
every supported format. To test a specific file type, set <code>FMTS</code> to the format
|
||
|
you want to test. Feature-specific tests are available with <code>make test_misc</code></p>
|
||
|
<div class="highlight highlight-source-shell"><pre>$ make test_misc <span class="pl-c"><span class="pl-c">#</span> run core tests</span>
|
||
|
$ make <span class="pl-c1">test</span> <span class="pl-c"><span class="pl-c">#</span> run full tests</span>
|
||
|
$ make test_xls <span class="pl-c"><span class="pl-c">#</span> only use the XLS test files</span>
|
||
|
$ make test_xlsx <span class="pl-c"><span class="pl-c">#</span> only use the XLSX test files</span>
|
||
|
$ make test_xlsb <span class="pl-c"><span class="pl-c">#</span> only use the XLSB test files</span>
|
||
|
$ make test_xml <span class="pl-c"><span class="pl-c">#</span> only use the XML test files</span>
|
||
|
$ make test_ods <span class="pl-c"><span class="pl-c">#</span> only use the ODS test files</span></pre></div>
|
||
|
<p>To enable all errors, set the environment variable <code>WTF=1</code>:</p>
|
||
|
<div class="highlight highlight-source-shell"><pre>$ make <span class="pl-c1">test</span> <span class="pl-c"><span class="pl-c">#</span> run full tests</span>
|
||
|
$ WTF=1 make <span class="pl-c1">test</span> <span class="pl-c"><span class="pl-c">#</span> enable all error messages</span></pre></div>
|
||
|
<p><code>flow</code> and <code>eslint</code> checks are available:</p>
|
||
|
<div class="highlight highlight-source-shell"><pre>$ make lint <span class="pl-c"><span class="pl-c">#</span> eslint checks</span>
|
||
|
$ make flow <span class="pl-c"><span class="pl-c">#</span> make lint + Flow checking</span>
|
||
|
$ make tslint <span class="pl-c"><span class="pl-c">#</span> check TS definitions</span></pre></div>
|
||
|
</details>
|
||
|
<h3>
|
||
|
<a id="user-content-browser" class="anchor" href="#browser" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Browser</h3>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<p>The core in-browser tests are available at <code>tests/index.html</code> within this repo.
|
||
|
Start a local server and navigate to that directory to run the tests.
|
||
|
<code>make ctestserv</code> will start a server on port 8000.</p>
|
||
|
<p><code>make ctest</code> will generate the browser fixtures. To add more files, edit the
|
||
|
<code>tests/fixtures.lst</code> file and add the paths.</p>
|
||
|
<p>To run the full in-browser tests, clone the repo for
|
||
|
<a href="https://github.com/SheetJS/SheetJS.github.io"><code>oss.sheetjs.com</code></a> and replace
|
||
|
the <code>xlsx.js</code> file (then open a browser window and go to <code>stress.html</code>):</p>
|
||
|
<div class="highlight highlight-source-shell"><pre>$ cp xlsx.js ../SheetJS.github.io
|
||
|
$ <span class="pl-c1">cd</span> ../SheetJS.github.io
|
||
|
$ simplehttpserver <span class="pl-c"><span class="pl-c">#</span> or "python -mSimpleHTTPServer" or "serve"</span>
|
||
|
$ open -a Chromium.app http://localhost:8000/stress.html</pre></div>
|
||
|
</details>
|
||
|
<h3>
|
||
|
<a id="user-content-tested-environments" class="anchor" href="#tested-environments" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Tested Environments</h3>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<ul>
|
||
|
<li>NodeJS <code>0.8</code>, <code>0.10</code>, <code>0.12</code>, <code>4.x</code>, <code>5.x</code>, <code>6.x</code>, <code>7.x</code>, <code>8.x</code>
|
||
|
</li>
|
||
|
<li>IE 6/7/8/9/10/11 (IE 6-9 require shims)</li>
|
||
|
<li>Chrome 24+ (including Android 4.0+)</li>
|
||
|
<li>Safari 6+ (iOS and Desktop)</li>
|
||
|
<li>Edge 13+, FF 18+, and Opera 12+</li>
|
||
|
</ul>
|
||
|
<p>Tests utilize the mocha testing framework. Travis-CI and Sauce Labs links:</p>
|
||
|
<ul>
|
||
|
<li>
|
||
|
<a href="https://travis-ci.org/SheetJS/js-xlsx" rel="nofollow">https://travis-ci.org/SheetJS/js-xlsx</a> for XLSX module in nodejs</li>
|
||
|
<li>
|
||
|
<a href="https://semaphoreci.com/sheetjs/js-xlsx" rel="nofollow">https://semaphoreci.com/sheetjs/js-xlsx</a> for XLSX module in nodejs</li>
|
||
|
<li>
|
||
|
<a href="https://travis-ci.org/SheetJS/SheetJS.github.io" rel="nofollow">https://travis-ci.org/SheetJS/SheetJS.github.io</a> for XLS* modules</li>
|
||
|
<li>
|
||
|
<a href="https://saucelabs.com/u/sheetjs" rel="nofollow">https://saucelabs.com/u/sheetjs</a> for XLS* modules using Sauce Labs</li>
|
||
|
</ul>
|
||
|
<p>The Travis-CI test suite also includes tests for various time zones. To change
|
||
|
the timezone locally, set the TZ environment variable:</p>
|
||
|
<div class="highlight highlight-source-shell"><pre>$ env TZ=<span class="pl-s"><span class="pl-pds">"</span>Asia/Kolkata<span class="pl-pds">"</span></span> WTF=1 make test_misc</pre></div>
|
||
|
</details>
|
||
|
<h3>
|
||
|
<a id="user-content-test-files" class="anchor" href="#test-files" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Test Files</h3>
|
||
|
<p>Test files are housed in <a href="https://github.com/SheetJS/test_files">another repo</a>.</p>
|
||
|
<p>Running <code>make init</code> will refresh the <code>test_files</code> submodule and get the files.
|
||
|
Note that this requires <code>svn</code>, <code>git</code>, <code>hg</code> and other commands that may not be
|
||
|
available. If <code>make init</code> fails, please download the latest version of the test
|
||
|
files snapshot from <a href="https://github.com/SheetJS/test_files/releases">the repo</a></p>
|
||
|
<details>
|
||
|
<summary><b>Latest Snapshot</b> (click to show)</summary>
|
||
|
<p>Latest test files snapshot:
|
||
|
<a href="http://github.com/SheetJS/test_files/releases/download/20170409/test_files.zip">http://github.com/SheetJS/test_files/releases/download/20170409/test_files.zip</a></p>
|
||
|
<p>(download and unzip to the <code>test_files</code> subdirectory)</p>
|
||
|
</details>
|
||
|
<h2>
|
||
|
<a id="user-content-contributing" class="anchor" href="#contributing" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Contributing</h2>
|
||
|
<p>Due to the precarious nature of the Open Specifications Promise, it is very
|
||
|
important to ensure code is cleanroom. <a href="CONTRIBUTING.md">Contribution Notes</a></p>
|
||
|
<details>
|
||
|
<summary><b>File organization</b> (click to show)</summary>
|
||
|
<p>At a high level, the final script is a concatenation of the individual files in
|
||
|
the <code>bits</code> folder. Running <code>make</code> should reproduce the final output on all
|
||
|
platforms. The README is similarly split into bits in the <code>docbits</code> folder.</p>
|
||
|
<p>Folders:</p>
|
||
|
<table>
|
||
|
<thead>
|
||
|
<tr>
|
||
|
<th align="left">folder</th>
|
||
|
<th align="left">contents</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td align="left"><code>bits</code></td>
|
||
|
<td align="left">raw source files that make up the final script</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>docbits</code></td>
|
||
|
<td align="left">raw markdown files that make up <code>README.md</code>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>bin</code></td>
|
||
|
<td align="left">server-side bin scripts (<code>xlsx.njs</code>)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>dist</code></td>
|
||
|
<td align="left">dist files for web browsers and nonstandard JS environments</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>demos</code></td>
|
||
|
<td align="left">demo projects for platforms like ExtendScript and Webpack</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>tests</code></td>
|
||
|
<td align="left">browser tests (run <code>make ctest</code> to rebuild)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>types</code></td>
|
||
|
<td align="left">typescript definitions and tests</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>misc</code></td>
|
||
|
<td align="left">miscellaneous supporting scripts</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td align="left"><code>test_files</code></td>
|
||
|
<td align="left">test files (pulled from the test files repository)</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
</details>
|
||
|
<p>After cloning the repo, running <code>make help</code> will display a list of commands.</p>
|
||
|
<h3>
|
||
|
<a id="user-content-osxlinux" class="anchor" href="#osxlinux" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>OSX/Linux</h3>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<p>The <code>xlsx.js</code> file is constructed from the files in the <code>bits</code> subdirectory. The
|
||
|
build script (run <code>make</code>) will concatenate the individual bits to produce the
|
||
|
script. Before submitting a contribution, ensure that running make will produce
|
||
|
the <code>xlsx.js</code> file exactly. The simplest way to test is to add the script:</p>
|
||
|
<div class="highlight highlight-source-shell"><pre>$ git add xlsx.js
|
||
|
$ make clean
|
||
|
$ make
|
||
|
$ git diff xlsx.js</pre></div>
|
||
|
<p>To produce the dist files, run <code>make dist</code>. The dist files are updated in each
|
||
|
version release and <em>should not be committed between versions</em>.</p>
|
||
|
</details>
|
||
|
<h3>
|
||
|
<a id="user-content-windows" class="anchor" href="#windows" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Windows</h3>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<p>The included <code>make.cmd</code> script will build <code>xlsx.js</code> from the <code>bits</code> directory.
|
||
|
Building is as simple as:</p>
|
||
|
<div class="highlight highlight-source-batchfile"><pre><span class="pl-k">></span> make</pre></div>
|
||
|
<p>To prepare development environment:</p>
|
||
|
<div class="highlight highlight-source-batchfile"><pre><span class="pl-k">></span> make init</pre></div>
|
||
|
<p>The full list of commands available in Windows are displayed in <code>make help</code>:</p>
|
||
|
<pre><code>make init -- install deps and global modules
|
||
|
make lint -- run eslint linter
|
||
|
make test -- run mocha test suite
|
||
|
make misc -- run smaller test suite
|
||
|
make book -- rebuild README and summary
|
||
|
make help -- display this message
|
||
|
</code></pre>
|
||
|
<p>As explained in <a href="#test-files">Test Files</a>, on Windows the release ZIP file must
|
||
|
be downloaded and extracted. If Bash on Windows is available, it is possible
|
||
|
to run the OSX/Linux workflow. The following steps prepares the environment:</p>
|
||
|
<div class="highlight highlight-source-shell"><pre><span class="pl-c"><span class="pl-c">#</span> Install support programs for the build and test commands</span>
|
||
|
sudo apt-get install make git subversion mercurial
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">#</span> Install nodejs and NPM within the WSL</span>
|
||
|
wget -qO- https://deb.nodesource.com/setup_8.x <span class="pl-k">|</span> sudo bash
|
||
|
sudo apt-get install nodejs
|
||
|
|
||
|
<span class="pl-c"><span class="pl-c">#</span> Install dev dependencies</span>
|
||
|
sudo npm install -g mocha voc blanket xlsjs</pre></div>
|
||
|
</details>
|
||
|
<h3>
|
||
|
<a id="user-content-tests" class="anchor" href="#tests" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Tests</h3>
|
||
|
<details>
|
||
|
<summary>(click to show)</summary>
|
||
|
<p>The <code>test_misc</code> target (<code>make test_misc</code> on Linux/OSX / <code>make misc</code> on Windows)
|
||
|
runs the targeted feature tests. It should take 5-10 seconds to perform feature
|
||
|
tests without testing against the entire test battery. New features should be
|
||
|
accompanied with tests for the relevant file formats and features.</p>
|
||
|
<p>For tests involving the read side, an appropriate feature test would involve
|
||
|
reading an existing file and checking the resulting workbook object. If a
|
||
|
parameter is involved, files should be read with different values to verify that
|
||
|
the feature is working as expected.</p>
|
||
|
<p>For tests involving a new write feature which can already be parsed, appropriate
|
||
|
feature tests would involve writing a workbook with the feature and then opening
|
||
|
and verifying that the feature is preserved.</p>
|
||
|
<p>For tests involving a new write feature without an existing read ability, please
|
||
|
add a feature test to the kitchen sink <code>tests/write.js</code>.</p>
|
||
|
</details>
|
||
|
<h2>
|
||
|
<a id="user-content-license" class="anchor" href="#license" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>License</h2>
|
||
|
<p>Please consult the attached LICENSE file for details. All rights not explicitly
|
||
|
granted by the Apache 2.0 License are reserved by the Original Author.</p>
|
||
|
<h2>
|
||
|
<a id="user-content-references" class="anchor" href="#references" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>References</h2>
|
||
|
<details>
|
||
|
<summary><b>OSP-covered Specifications</b> (click to show)</summary>
|
||
|
<ul>
|
||
|
<li>
|
||
|
<code>MS-CFB</code>: Compound File Binary File Format</li>
|
||
|
<li>
|
||
|
<code>MS-CTXLS</code>: Excel Custom Toolbar Binary File Format</li>
|
||
|
<li>
|
||
|
<code>MS-EXSPXML3</code>: Excel Calculation Version 2 Web Service XML Schema</li>
|
||
|
<li>
|
||
|
<code>MS-ODATA</code>: Open Data Protocol (OData)</li>
|
||
|
<li>
|
||
|
<code>MS-ODRAW</code>: Office Drawing Binary File Format</li>
|
||
|
<li>
|
||
|
<code>MS-ODRAWXML</code>: Office Drawing Extensions to Office Open XML Structure</li>
|
||
|
<li>
|
||
|
<code>MS-OE376</code>: Office Implementation Information for ECMA-376 Standards Support</li>
|
||
|
<li>
|
||
|
<code>MS-OFFCRYPTO</code>: Office Document Cryptography Structure</li>
|
||
|
<li>
|
||
|
<code>MS-OI29500</code>: Office Implementation Information for ISO/IEC 29500 Standards Support</li>
|
||
|
<li>
|
||
|
<code>MS-OLEDS</code>: Object Linking and Embedding (OLE) Data Structures</li>
|
||
|
<li>
|
||
|
<code>MS-OLEPS</code>: Object Linking and Embedding (OLE) Property Set Data Structures</li>
|
||
|
<li>
|
||
|
<code>MS-OODF3</code>: Office Implementation Information for ODF 1.2 Standards Support</li>
|
||
|
<li>
|
||
|
<code>MS-OSHARED</code>: Office Common Data Types and Objects Structures</li>
|
||
|
<li>
|
||
|
<code>MS-OVBA</code>: Office VBA File Format Structure</li>
|
||
|
<li>
|
||
|
<code>MS-XLDM</code>: Spreadsheet Data Model File Format</li>
|
||
|
<li>
|
||
|
<code>MS-XLS</code>: Excel Binary File Format (.xls) Structure Specification</li>
|
||
|
<li>
|
||
|
<code>MS-XLSB</code>: Excel (.xlsb) Binary File Format</li>
|
||
|
<li>
|
||
|
<code>MS-XLSX</code>: Excel (.xlsx) Extensions to the Office Open XML SpreadsheetML File Format</li>
|
||
|
<li>
|
||
|
<code>XLS</code>: Microsoft Office Excel 97-2007 Binary File Format Specification</li>
|
||
|
<li>
|
||
|
<code>RTF</code>: Rich Text Format</li>
|
||
|
</ul>
|
||
|
</details>
|
||
|
<ul>
|
||
|
<li>ISO/IEC 29500:2012(E) "Information technology — Document description and processing languages — Office Open XML File Formats"</li>
|
||
|
<li>Open Document Format for Office Applications Version 1.2 (29 September 2011)</li>
|
||
|
<li>Worksheet File Format (From Lotus) December 1984</li>
|
||
|
</ul>
|
||
|
|
||
|
</article>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
|
||
|
|
||
|
</div>
|
||
|
<div> </div>
|
||
|
</div><script>
|
||
|
function showCanonicalImages() {
|
||
|
var images = document.getElementsByTagName('img');
|
||
|
if (!images) {
|
||
|
return;
|
||
|
}
|
||
|
for (var index = 0; index < images.length; index++) {
|
||
|
var image = images[index];
|
||
|
if (image.getAttribute('data-canonical-src') && image.src !== image.getAttribute('data-canonical-src')) {
|
||
|
image.src = image.getAttribute('data-canonical-src');
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function scrollToHash() {
|
||
|
if (location.hash && !document.querySelector(':target')) {
|
||
|
var element = document.getElementById('user-content-' + location.hash.slice(1));
|
||
|
if (element) {
|
||
|
element.scrollIntoView();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function autorefreshContent(eventSourceUrl) {
|
||
|
var initialTitle = document.title;
|
||
|
var contentElement = document.getElementById('grip-content');
|
||
|
var source = new EventSource(eventSourceUrl);
|
||
|
var isRendering = false;
|
||
|
|
||
|
source.onmessage = function(ev) {
|
||
|
var msg = JSON.parse(ev.data);
|
||
|
if (msg.updating) {
|
||
|
isRendering = true;
|
||
|
document.title = '(Rendering) ' + document.title;
|
||
|
} else {
|
||
|
isRendering = false;
|
||
|
document.title = initialTitle;
|
||
|
contentElement.innerHTML = msg.content;
|
||
|
showCanonicalImages();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
source.onerror = function(e) {
|
||
|
if (e.readyState === EventSource.CLOSED && isRendering) {
|
||
|
isRendering = false;
|
||
|
document.title = initialTitle;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
window.onhashchange = function() {
|
||
|
scrollToHash();
|
||
|
}
|
||
|
|
||
|
window.onload = function() {
|
||
|
scrollToHash();
|
||
|
}
|
||
|
|
||
|
showCanonicalImages();
|
||
|
|
||
|
var autorefreshUrl = document.getElementById('preview-page').getAttribute('data-autorefresh-url');
|
||
|
if (autorefreshUrl) {
|
||
|
autorefreshContent(autorefreshUrl);
|
||
|
}
|
||
|
</script>
|
||
|
</body>
|
||
|
</html>
|