read-excel-file
Version:
Read small to medium `*.xlsx` files in a browser or Node.js. Parse to JSON with a strict schema.
262 lines (224 loc) • 6.2 kB
HTML
<html>
<head>
<title>read-excel-file</title>
<meta charset="utf-8">
<script src="./read-excel-file.min.js"></script>
<script src="./lib/promise-polyfill.min.js"></script>
<script src="./lib/prism.js"></script>
<style>
body
{
margin : 20px;
font-family : Arial, Helvetica;
background: #434343;
color: #dddddd;
}
#input
{
margin-top : 20px;
margin-bottom : 10px;
}
#result-table table
{
width : 100%;
border-collapse : collapse;
margin-top : 2.5em;
margin-bottom : 2.5em;
font-size : 12px;
}
#result-table table td
{
border : 1px solid black;
padding : 0.5em;
text-overflow : ellipsis;
overflow : hidden;
max-width : 10em;
white-space : nowrap;
}
#main-link
{
display : block;
font-size : 24px;
color : #fd8900;
font-family : monospace;
text-decoration : none;
}
a
{
color: #fd8900;
}
.file-upload
{
text-transform: uppercase;
letter-spacing: 1px;
font-size: 0.75rem;
color: #fd8900;
border: 1px solid currentColor;
border-radius: 4px;
display: inline-block;
padding: 6px 12px;
cursor: pointer;
}
.file-upload:active
{
color: black;
font-weight: bolder;
background-color: #fd8900;
}
input[type="file"]
{
display: none;
}
#result,
#error,
#loading
{
display: none;
margin-top: 2.5rem;
}
#error
{
color: #ff7979;
}
/* Loading Indicator */
/* https://loading.io/css/ */
.lds-ellipsis {
display: inline-block;
position: relative;
width: 40px;
height: 40px;
}
.lds-ellipsis div {
position: absolute;
top: 16px;
width: 7px;
height: 7px;
border-radius: 50%;
background: #fff;
animation-timing-function: cubic-bezier(0, 1, 1, 0);
}
.lds-ellipsis div:nth-child(1) {
left: 4px;
animation: lds-ellipsis1 0.6s infinite;
}
.lds-ellipsis div:nth-child(2) {
left: 4px;
animation: lds-ellipsis2 0.6s infinite;
}
.lds-ellipsis div:nth-child(3) {
left: 16px;
animation: lds-ellipsis2 0.6s infinite;
}
.lds-ellipsis div:nth-child(4) {
left: 28px;
animation: lds-ellipsis3 0.6s infinite;
}
@keyframes lds-ellipsis1 {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
@keyframes lds-ellipsis3 {
0% {
transform: scale(1);
}
100% {
transform: scale(0);
}
}
@keyframes lds-ellipsis2 {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(12px, 0);
}
}
</style>
<link href="lib/prism.css" rel="stylesheet" />
</head>
<body>
<a id="main-link" href="https://gitlab.com/catamphetamine/read-excel-file">
read-excel-file
</a>
<br/>
<div style="line-height: 1.35em">
Read small to medium <code>*.xlsx</code> files in a browser or Node.js.
</div>
<div style="line-height: 1.35em; margin-top: 0.35em">
Parse file data to an array of JSON objects using a schema.
</div>
<br/>
<label for="input" class="file-upload">
Click here to choose an <code>*.xlsx</code> file
</label>
<input type="file" id="input" />
<div id="loading">
<div class="lds-ellipsis"><div></div><div></div><div></div><div></div></div>
</div>
<div id="error">
</div>
<div id="result">
<h2>
File Data
</h2>
<div style="margin-top: 1rem">
Also supports parsing file data to an array of JSON objects using a schema. <a target="_blank" href="https://gitlab.com/catamphetamine/read-excel-file#json" style="text-decoration: none">Read more</a>
</div>
<br/>
<div id="result-table"></div>
<pre><code class="language-js" id="result-data"></code></pre>
</div>
<script>
var input = document.getElementById('input')
input.addEventListener('change', function() {
document.getElementById('result').style.display = 'none'
document.getElementById('error').style.display = 'none'
document.getElementById('loading').style.display = 'block'
if (!input.files[0]) {
return document.getElementById('loading').style.display = 'none'
}
readXlsxFile(input.files[0]).then(function(data) {
// `data` is an array of rows
// each row being an array of cells.
// document.getElementById('result').innerText = JSON.stringify(data, null, 2)
document.getElementById('loading').style.display = 'none'
document.getElementById('result').style.display = 'block'
document.getElementById('result-data').innerHTML = Prism.highlight(
JSON.stringify(data, null, 2),
Prism.languages.javascript,
'javascript'
)
// Applying `innerHTML` hangs the browser when there're a lot of rows/columns.
// For example, for a file having 2000 rows and 20 columns on a modern
// mid-tier CPU it parses the file (using a "schema") for 3 seconds
// (blocking) with 100% single CPU core usage.
// Then applying `innerHTML` hangs the browser.
// document.getElementById('result-table').innerHTML =
// '<table>' +
// '<tbody>' +
// data.map(function (row) {
// return '<tr>' +
// row.map(function (cell) {
// return '<td>' +
// (cell === null ? '' : cell) +
// '</td>'
// }).join('') +
// '</tr>'
// }).join('') +
// '</tbody>' +
// '</table>'
}, function (error) {
console.error(error)
// alert("Error while parsing Excel file. See console output for the error stack trace.")
document.getElementById('loading').style.display = 'none'
document.getElementById('error').style.display = 'block'
document.getElementById('error').innerText = error.message
})
})
</script>
</body>
</html>