> I am creating and downloading excel file with data that I have gotten in JSON format. Now I want to add status column in last and provide list data validation there with three specified value "rejected","sleected" and "on-hold"
downloadTableData(data, headers) {
this.dataToDownload = "";
let dataSourceLength = data.length;
let rowData = '';
for (let i = 0; i < dataSourceLength; i++) {
let line = '';
for (let key in data[i]) {
if (line != '') {
line = line + ','
}
line = line + data[i][key];
}
rowData = rowData + line + "\r\n";
}
// as of now; but based on api data, row data and column dat ashould be done
this.dataToDownload = this.dataToDownload + headers.join(',') + "\r\n" + rowData;
if (this.dataToDownload.split('\n').length - 1 >= 1) {
// const fileName = 'reports-' + new Date();
const fileName ='Upload_template.xlsx';
let anchor = document.createElement('a');
anchor.href = URL.createObjectURL(new Blob([this.dataToDownload], { type: 'text/csv' }));
anchor.download = fileName + '.csv';
// anchor.download = fileName;
// start download
anchor.click();
}
}
Here is the sample code how to apply data validation
const nameSourceRange = context.workbook.worksheets.getItem("Status").getRange("A1:A3");
let approvedListRule = {
list: {
inCellDropDown: true,
source: nameSourceRange
}
};
nameRange.dataValidation.rule = approvedListRule;
I created a gist for you to demo how to add the approved status.
https://gist.github.com/lumine2008/827ab26a65b76a5826331d960323c43b
I found the solution with the help of excel.js and file-saver.js.
import { Workbook } from 'exceljs';
import * as fs from 'file-saver';
generateExcel(list,header) {
let data:any = [];
for(let i=0;i<list.length;i++){
let arr = [list[i].requisitionId,list[i].applicationid, list[i].candidateid, list[i].unitcode];
data.push(arr);
}
console.log(data);
//Create workbook and worksheet
let workbook = new Workbook();
let worksheet = workbook.addWorksheet('Candidate Report');
//Add Header Row
let headerRow = worksheet.addRow(header);
// Cell Style : Fill and Border
headerRow.eachCell((cell, number) => {
cell.fill = {
type: 'pattern',
pattern: 'solid',
fgColor: { argb: 'FFFFFF00' },
bgColor: { argb: 'FF0000FF' }
}
cell.border = { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' } }
})
worksheet.getColumn(3).width = 30;
data.forEach(d => {
let row = worksheet.addRow(d);
}
);
list.forEach((element,index) =>{
worksheet.getCell('E'+(+index+2)).dataValidation = {
type: 'list',
allowBlank: true,
formulae: ['"Selected,Rejected,On-hold"']
};
})
//Generate Excel File with given name
workbook.xlsx.writeBuffer().then((data) => {
let blob = new Blob([data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
fs.saveAs(blob, 'candidate.xlsx');
})
}
`
Related
I want to export the current google sheet data into pdf page but I do want a page break at row 10 so that any data after row 10 goes on to the next page. This means there will be multiple pages for more data. I do not want to print all data on one page. The final pdf file should have multiple pages for data that crosses row 10 in the google sheet
var saveToRootFolder = false
function onOpen() {
SpreadsheetApp.getUi()
.createAddonMenu()
.addItem('Export all sheets', 'exportAsPDF')
.addItem('Export all sheets as separate files', 'exportAllSheetsAsSeparatePDFs')
.addItem('Export current sheet', 'exportCurrentSheetAsPDF')
.addItem('Export selected area', 'exportPartAsPDF')
.addItem('Export predefined area', 'exportNamedRangesAsPDF')
.addToUi()
}
function _exportBlob(blob, fileName, spreadsheet) {
blob = blob.setName(SpreadsheetApp.getActiveSheet().getRange('E4:G4').getValue())
var folder = saveToRootFolder ? DriveApp : DriveApp.getFileById(spreadsheet.getId()).getParents().next()
var pdfFile = folder.createFile(blob)
var folder = DriveApp.getFolderById("FOLDER_ID");
pdfFile.moveTo(folder);
// Display a modal dialog box with custom HtmlService content.
const htmlOutput = HtmlService
.createHtmlOutput('<p>Click to open ' + fileName + '</p>')
.setWidth(300)
.setHeight(80)
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Export Successful')
}
function exportAsPDF() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet()
var blob = _getAsBlob(spreadsheet.getUrl())
_exportBlob(blob, spreadsheet.getName(), spreadsheet)
}
function _getAsBlob(url, sheet, range) {
var rangeParam = ''
var sheetParam = ''
if (range) {
rangeParam =
'&r1=' + (range.getRow() - 1)
+ '&r2=' + range.getLastRow()
+ '&c1=' + (range.getColumn() - 1)
+ '&c2=' + range.getLastColumn()
}
if (sheet) {
sheetParam = '&gid=' + sheet.getSheetId()
}
// A credit to https://gist.github.com/Spencer-Easton/78f9867a691e549c9c70
// these parameters are reverse-engineered (not officially documented by Google)
// they may break overtime.
var exportUrl = url.replace(/\/edit.*$/, '')
+ '/export?exportFormat=pdf&format=pdf'
+ '&size=A4'
+ '&portrait=true'
+ '&fitw=true'
+ '&top_margin=0.2'
+ '&bottom_margin=0.2'
+ '&left_margin=0.2'
+ '&right_margin=0.1'
+ '&scale=3'
+ '&sheetnames=false&printtitle=false'
+ '&pagenum=UNDEFINED' // change it to CENTER to print page numbers
+ '&gridlines=true'
+ '&fzr=FALSE'
+ sheetParam
+ rangeParam
Logger.log('exportUrl=' + exportUrl)
var response
var i = 0
for (; i < 5; i += 1) {
response = UrlFetchApp.fetch(exportUrl, {
muteHttpExceptions: true,
headers: {
Authorization: 'Bearer ' + ScriptApp.getOAuthToken(),
},
})
if (response.getResponseCode() === 429) {
// printing too fast, retrying
Utilities.sleep(3000)
} else {
break
}
}
if (i === 5) {
throw new Error('Printing failed. Too many sheets to print.')
}
return response.getBlob()
}
function exportAllSheetsAsSeparatePDFs() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet()
var files = []
var folder = saveToRootFolder ? DriveApp : DriveApp.getFileById(spreadsheet.getId()).getParents().next()
spreadsheet.getSheets().forEach(function (sheet) {
spreadsheet.setActiveSheet(sheet)
var blob = _getAsBlob(spreadsheet.getUrl(), sheet)
var fileName = sheet.getName()
blob = blob.setName(fileName)
var pdfFile = folder.createFile(blob)
files.push({
url: pdfFile.getUrl(),
name: fileName,
})
})
const htmlOutput = HtmlService
.createHtmlOutput('<p>Click to open PDF files</p>'
+ '<ul>'
+ files.reduce(function (prev, file) {
prev += '<li>' + file.name + '</li>'
return prev
}, '')
+ '</ul>')
.setWidth(300)
.setHeight(150)
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Export Successful')
}
function exportCurrentSheetAsPDF() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet()
var currentSheet = SpreadsheetApp.getActiveSheet()
var blob = _getAsBlob(spreadsheet.getUrl(), currentSheet)
_exportBlob(blob, currentSheet.getName(), spreadsheet)
}
function exportPartAsPDF(predefinedRanges) {
var ui = SpreadsheetApp.getUi()
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet()
var selectedRanges
var fileSuffix
if (predefinedRanges) {
selectedRanges = predefinedRanges
fileSuffix = '-predefined'
} else {
var activeRangeList = spreadsheet.getActiveRangeList()
if (!activeRangeList) {
ui.alert('Please select at least one range to export')
return
}
selectedRanges = activeRangeList.getRanges()
fileSuffix = '-selected'
}
if (selectedRanges.length === 1) {
// special export with formatting
var currentSheet = selectedRanges[0].getSheet()
var blob = _getAsBlob(spreadsheet.getUrl(), currentSheet, selectedRanges[0])
var fileName = spreadsheet.getName() + fileSuffix
_exportBlob(blob, fileName, spreadsheet)
return
}
var tempSpreadsheet = SpreadsheetApp.create(spreadsheet.getName() + fileSuffix)
if (!saveToRootFolder) {
DriveApp.getFileById(tempSpreadsheet.getId()).moveTo(DriveApp.getFileById(spreadsheet.getId()).getParents().next())
}
var tempSheets = tempSpreadsheet.getSheets()
var sheet1 = tempSheets.length > 0 ? tempSheets[0] : undefined
SpreadsheetApp.setActiveSpreadsheet(tempSpreadsheet)
tempSpreadsheet.setSpreadsheetTimeZone(spreadsheet.getSpreadsheetTimeZone())
tempSpreadsheet.setSpreadsheetLocale(spreadsheet.getSpreadsheetLocale())
for (var i = 0; i < selectedRanges.length; i++) {
var selectedRange = selectedRanges[i]
var originalSheet = selectedRange.getSheet()
var originalSheetName = originalSheet.getName()
var destSheet = tempSpreadsheet.getSheetByName(originalSheetName)
if (!destSheet) {
destSheet = tempSpreadsheet.insertSheet(originalSheetName)
}
Logger.log('a1notation=' + selectedRange.getA1Notation())
var destRange = destSheet.getRange(selectedRange.getA1Notation())
destRange.setValues(selectedRange.getValues())
destRange.setTextStyles(selectedRange.getTextStyles())
destRange.setBackgrounds(selectedRange.getBackgrounds())
destRange.setFontColors(selectedRange.getFontColors())
destRange.setFontFamilies(selectedRange.getFontFamilies())
destRange.setFontLines(selectedRange.getFontLines())
destRange.setFontStyles(selectedRange.getFontStyles())
destRange.setFontWeights(selectedRange.getFontWeights())
destRange.setHorizontalAlignments(selectedRange.getHorizontalAlignments())
destRange.setNumberFormats(selectedRange.getNumberFormats())
destRange.setTextDirections(selectedRange.getTextDirections())
destRange.setTextRotations(selectedRange.getTextRotations())
destRange.setVerticalAlignments(selectedRange.getVerticalAlignments())
destRange.setWrapStrategies(selectedRange.getWrapStrategies())
}
// remove empty Sheet1
if (sheet1) {
Logger.log('lastcol = ' + sheet1.getLastColumn() + ',lastrow=' + sheet1.getLastRow())
if (sheet1 && sheet1.getLastColumn() === 0 && sheet1.getLastRow() === 0) {
tempSpreadsheet.deleteSheet(sheet1)
}
}
exportAsPDF()
SpreadsheetApp.setActiveSpreadsheet(spreadsheet)
DriveApp.getFileById(tempSpreadsheet.getId()).setTrashed(true)
}
function exportNamedRangesAsPDF() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet()
var allNamedRanges = spreadsheet.getNamedRanges()
var toPrintNamedRanges = []
for (var i = 0; i < allNamedRanges.length; i++) {
var namedRange = allNamedRanges[i]
if (/^print_area_.*$/.test(namedRange.getName())) {
Logger.log('found named range ' + namedRange.getName())
toPrintNamedRanges.push(namedRange.getRange())
}
}
if (toPrintNamedRanges.length === 0) {
SpreadsheetApp.getUi().alert('No print areas found. Please add at least one \'print_area_1\' named range in the menu Data > Named ranges.')
return
} else {
toPrintNamedRanges.sort(function (a, b) {
return a.getSheet().getIndex() - b.getSheet().getIndex()
})
exportPartAsPDF(toPrintNamedRanges)
}
}
I developed an example script to test the approach described in my comment. I'll leave it here for future reference, but feel free to leave a comment if you have any doubt about it. This is the final script:
function exportRowsToPDF() {
var importantRows = [2, 13, 14, 15, 19]; // Exported rows
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var originalSheet = SpreadsheetApp.getActiveSheet();
var sheets = spreadsheet.getSheets();
var tempSheet = spreadsheet.insertSheet("TEMP", 10);
var maxColumn = originalSheet.getLastColumn();
for (var i = 0; i < importantRows.length; i++) {
tempSheet.appendRow(originalSheet.getRange(importantRows[i], 1, 1, maxColumn)
.getValues()[0]);
}
for (var i = 0; i < sheets.length; i++) {
if (sheets[i].getSheetName() !== "TEMP") {
sheets[i].hideSheet();
}
}
DriveApp.createFile(spreadsheet.getBlob().setName("Exported Sheet"));
for (var i = 0; i < sheets.length; i++) {
sheets[i].showSheet();
}
spreadsheet.deleteSheet(tempSheet);
}
You can modify the script to export any particular rows, but I used five of them for testing. This script will create a new sheet on your spreadsheet, and it will copy any relevant row there. Then, it will hide every sheet minus the newly created one. After that it will export the spreadsheet as a PDF blob directly to your Drive. Finally, it will reset the spreadsheet to the original state (by removing the created sheet and unhiding every other sheet). This code uses the same methods as your example, but write to me if you want to clarify any point.
I need to read only visible rows from an excel file.
Now I am getting with all rows in excel file while using the following code.
let fileReader = new FileReader();
fileReader.readAsBinaryString(selectedFile);
fileReader.onload = (event) => {
let data = event.target.result;
let workbook = XLSX.read(data, { type: "binary" });
let rowObject = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[workbook.SheetNames[j]]);
import * as Excel from "exceljs/dist/exceljs.min.js";
checkHiddenRowAndColumns(file) {
const workbook = new Excel.Workbook();
const arryBuffer = new Response(file).arrayBuffer();
arryBuffer.then(function (data) {
workbook.xlsx.load(data)
.then(function () {
const worksheet = workbook.getWorksheet(1);
//check hidden columns
for(var i=0; i < worksheet.columns.length; i++) {
if(worksheet.columns[i].hidden == true){
console.log('hidden columns' + i)
}
}
//check hidden rows
worksheet.eachRow(function (row,rowNumber) {
if(row.hidden == true) {
console.log('hidden row' + rowNumber)
}
});
this.spinnerService.hide();
});
});
}
onFileChange(evt: any) {
this.spinnerService.show();
this.data = [];
this.uploadedFileName = '';
/* wire up file reader */
const target: DataTransfer = <DataTransfer>(evt.target);
if (target.files.length > 1) throw new Error('Cannot use multiple files');
if (target.files.length === 1) {
this.checkHiddenRowAndColumns(target.files[0]);
this.enableImportExcel = true;
const file = target.files[0];
this.searchFilterForm.get('edt').setValue(file);
this.uploadedFileName = target.files[0].name;
if (target.files.length == 1 && (target.files[0].type == ".xlsx" || target.files[0].type == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" || target.files[0].type == "application/vnd.ms-excel")) {
const reader: FileReader = new FileReader();
reader.onload = (e: any) => {
/* read workbook */
const bstr: string = e.target.result;
const wb: XLSX.WorkBook = XLSX.read(bstr, { type: 'binary' });
/* grab first sheet */
const wsname: string = wb.SheetNames[0];
const ws: XLSX.WorkSheet = wb.Sheets[wsname];
this.data = (XLSX.utils.sheet_to_json(ws, { header: 1, raw: false }));
};
reader.readAsBinaryString(target.files[0]);
}
else {
this.enableImportExcel = false;
}
} else {
this.uploadedFileName = "";
}
}
There is skip hidden row option in sheet_to_csv method I just used it and reparse the output:
function xslxRemoveSheetHiddenRows(sheet){
let csv=XLSX.utils.sheet_to_csv(sheet,{skipHidden:true})
let filteredWorkbook=XLSX.read(csv, {type: 'binary'});
return filteredWorkbook.Sheets.Sheet1;
}
And usage example:
//loading cell's style is essential to detect hidden rows and columns
let workbook = XLSX.read(data, { type: 'binary', cellStyles: true });
//unhide the title rows to save it from elimination
workbook.Sheets.Data["!rows"][0].hidden = false;
//removing hidden rows and columns
let sheet = xslxRemoveSheetHiddenRows(workbook.Sheets.Data);
So I'm writing a simple web app that all it does is load a CSV, add an "agree?" checkbox to the end of each row, then downloads the table as CSV.
That downloaded CSV will later be converted to an SQL table, but before that, I need to find a way to give each row a boolean variable based on what the user checked or didn't check.
So here's the JS which is built out of a few functions that load a CSV, add the checkbox I mentioned, then convert it back.
function buildHeaderElement (header) {
const headerEl = document.createElement('thead')
headerEl.append(buildRowElement(header, true))
return headerEl
}
function buildRowElement (row, header) {
const columns = row.split(',')
const rowEl = document.createElement('tr')
for (column of columns) {
const columnEl = document.createElement(`${header ? 'th' : 'td'}`)
columnEl.textContent = column
rowEl.append(columnEl)
}
rowEl.append(provideeColumnAgree(row, header))
return rowEl
}
function provideeColumnAgree(row, header) {
const columnAgree = document.createElement(`${header ? 'th' : 'td'}`)
if(header)
{
columnAgree.textContent = 'Agree?';
}
else
{
const checkboxAgree = document.createElement(`input`)
checkboxAgree.setAttribute("type", "checkbox");
columnAgree.append(checkboxAgree)
}
return columnAgree
}
function populateTable (tableEl, rows) {
const rowEls = [buildHeaderElement(rows.shift())]
for (const row of rows) {
if (!row) { continue }
rowEls.push(buildRowElement(row))
}
tableEl.innerHTML= ''
return tableEl.append(...rowEls)
}
function createSubmitBtn() {
var button = document.createElement("button");
button.innerHTML = "Download CSV";
var body = document.getElementsByTagName("body")[0];
body.appendChild(button);
button.addEventListener ("click", function() {
exportTableToCSV('members.csv')
});
}
function downloadCSV(csv, filename) {
var csvFile;
var downloadLink;
// CSV file
csvFile = new Blob([csv], {type: "text/csv"});
downloadLink = document.createElement("a");
downloadLink.download = filename;
downloadLink.href = window.URL.createObjectURL(csvFile);
downloadLink.style.display = "none";
downloadLink.click();
}
function exportTableToCSV(filename) {
var csv = [];
var rows = document.querySelectorAll("table tr");
for (var i = 0; i < rows.length; i++) {
var row = [], cols = rows[i].querySelectorAll("td, th");
for (var j = 0; j < cols.length; j++)
row.push(cols[j].innerText);
csv.push(row.join(","));
}
// Download CSV file
downloadCSV(csv.join("\n"), filename);
}
function readSingleFile ({ target: { files } }) {
const file = files[0]
const fileReader = new FileReader()
const status = document.getElementById('status')
if (!file) {
status.textContent = 'No file selected.'
return
}
fileReader.onload = function ({ target: { result: contents } }) {
status.textContent = `File loaded: ${file.name}`
const tableEl = document.getElementById('csvOutput')
const lines = contents.split('\n')
populateTable(tableEl, lines)
status.textContent = `Table built from: ${file.name}`
createSubmitBtn()
}
fileReader.readAsText(file)
}
window.addEventListener('DOMContentLoaded', _ => {
document.getElementById('fileSelect').addEventListener('change', readSingleFile)
})
The HTML is quite simple
<html>
<body>
<input type="file" id="fileSelect"/>
<div id="status">Waiting for CSV file.</div>
<table id="csvOutput"></table>
<script src="script.js"></script>
</body>
</html>
Here's the link to the project: https://jsfiddle.net/95tjsom3/1/
While downloading the csv, you can check whether the column contains checkbox or not. And if it has a checkbox, whether it is checked or not. Then you can alter the contents of that particular column.
function exportTableToCSV(filename) {
var checkboxes = document.getElementsByTagName("input"); // get all checkboxes in the array
var csv = [];
var rows = document.querySelectorAll("table tr");
for (var i = 0; i < rows.length; i++) {
var row = [], cols = rows[i].querySelectorAll("td, th");
for (var j = 0; j < cols.length; j++) {
if(cols[j].innerHTML.includes('<input type="checkbox">')) {
if(checkboxes[i].checked) {
row.push("AGREE");
}
else {
row.push("NOT AGREE");
}
}
else {
row.push(cols[j].innerText);
}
}
csv.push(row.join(","));
}
// Download CSV file
downloadCSV(csv.join("\n"), filename);
}
I want to sore an image file to my local storage in order to reuse it on a different page. Im getting a picture or a file when on desktop. That should be transferred to a file and then I want to store it the onImagePicked function. I have connected that function with a button so the image should be transformed to a file and also be stored then. But somehow the func. is not called because I don't get my console.log. I suppose it could have to do something that Im just testing with pictures that come directly from my desktop and not with pictures from a device. But I don't know.
Here is my code: (The rest with getting and displaying the picture works)
import { Storage } from '#ionic/storage';
// convert base64 image into a file
function base64toBlob(base64Data, contentType) {
contentType = contentType || '';
const sliceSize = 1024;
const byteCharacters = atob(base64Data);
const bytesLength = byteCharacters.length;
const slicesCount = Math.ceil(bytesLength / sliceSize);
const byteArrays = new Array(slicesCount);
for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
const begin = sliceIndex * sliceSize;
const end = Math.min(begin + sliceSize, bytesLength);
const bytes = new Array(end - begin);
for (let offset = begin, i = 0; offset < end; ++i, ++offset) {
bytes[i] = byteCharacters[offset].charCodeAt(0);
}
byteArrays[sliceIndex] = new Uint8Array(bytes);
}
return new Blob(byteArrays, { type: contentType });
}
export const IMAGE_DATA = 'image_data';
...
#ViewChild('filePicker') filePickerRef: ElementRef<HTMLInputElement>;
#Output() imagePick = new EventEmitter<string | File>();
selectedImage: string;
usePicker = false;
...
takePicture() {
if (this.usePicker) {
this.filePickerRef.nativeElement.click();
}
Plugins.Camera.getPhoto({
quality: 80,
source: CameraSource.Prompt,
correctOrientation: true,
saveToGallery: true,
allowEditing: true,
resultType: CameraResultType.Base64,
direction: CameraDirection.Front
}).then(image => {
this.selectedImage = image.base64String;
this.imagePick.emit(image.base64String);
}).catch(error => {
console.log(error);
return false;
});
}
onImagePicked(imageData: string | File) {
let imageFile;
if (typeof imageData === 'string') {
try {
imageFile = base64toBlob(imageData.replace('data:image/jpeg;base64,', ''), 'image/jpeg');
this.storage.set('image_data', imageFile);
console.log('stored');
} catch (error) {
console.log(error);
}
} else {
imageFile = imageData;
}
}
onFileChosen(event: Event) {
const pickedFile = (event.target as HTMLInputElement).files[0];
const fr = new FileReader();
fr.onload = () => {
const dataUrl = fr.result.toString();
this.selectedImage = dataUrl;
this.imagePick.emit(pickedFile);
};
fr.readAsDataURL(pickedFile);
}
html (where I try to call the function)
<app-make-photo (imagePick)="onImagePicked($event)"></app-make-photo>
I am currently creating a web application that allows a user to upload an excel file into a database but before the user uploads the file I would like to allow them to check the headers of the excel file if it matches the preset on the database.
The code below allows me to display everything on the excel file:
$('#inputfile').change(function(e){
var reader = new FileReader();
reader.readAsArrayBuffer(e.target.files[0]);
reader.onload = function(e) {
var data = new Uint8Array(reader.result);
var wb = XLSX.read(data,{type:'array'});
var htmlstr = XLSX.write(wb,{sheet:"Sheet1", type:'binary',bookType:'html'});
$('#printHere')[0].innerHTML += htmlstr;
}
});
I would like to only store the excel file's header in an array and display it.
I'm new to Javascript so any help would be much appreciated.
You can do something like:
const header = []
const columnCount = XLSX.utils.decode_range(ws['!ref']).e.c + 1
for (let i = 0; i < columnCount; ++i) {
header[i] = ws[`${XLSX.utils.encode_col(i)}1`].v
}
Here is the whole example:
function extractHeader(ws) {
const header = []
const columnCount = XLSX.utils.decode_range(ws['!ref']).e.c + 1
for (let i = 0; i < columnCount; ++i) {
header[i] = ws[`${XLSX.utils.encode_col(i)}1`].v
}
return header
}
function handleFile() {
const input = document.getElementById("file")
const file = input.files[0]
if (file.type !== 'application/vnd.ms-excel') {
renderError()
}
const reader = new FileReader()
const rABS = !!reader.readAsBinaryString
reader.onload = e => {
/* Parse data */
const bstr = e.target.result
const wb = XLSX.read(bstr, { type: rABS ? 'binary' : 'array' })
/* Get first worksheet */
const wsname = wb.SheetNames[0]
const ws = wb.Sheets[wsname]
const header = extractHeader(ws)
renderTable(header)
}
if (rABS) reader.readAsBinaryString(file)
else reader.readAsArrayBuffer(file)
}
function renderTable(header) {
const table = document.createElement('table')
const tr = document.createElement('tr')
for (let i in header) {
const td = document.createElement('td')
const txt = document.createTextNode(header[i])
td.appendChild(txt)
tr.appendChild(td)
}
table.appendChild(tr)
document.getElementById('result').appendChild(table)
}
function renderError() {
const errorMsg = 'Unexpected file type'
const error = document.createElement('p')
error.setAttribute('class', 'error')
const txt = document.createTextNode(errorMsg)
error.appendChild(txt)
document.getElementById('result').appendChild(error)
throw new Error(errorMsg)
}
#result table tr td {
border: 2px solid grey;
}
#result .error {
color: red;
}
<script src="https://unpkg.com/xlsx/dist/xlsx.full.min.js"></script>
<input type="file" onchange="handleFile()" id='file' accept=".csv"/>
<div id="result"><div>