The below code fetches data from a csv and presents in to a div as a text but am trying to convert that in to a query on fetch excel import and print then as a query
Current output when the data is imported from the excel
Example:
column1','column2','column3','column4')
column1','column2','column3','column4')
column1','column2','column3','column4')
column1','column2','column3','column4')
column1','column2','column3','column4')
Expected output
('column1','column2','column3','column4'),
('column1','column2','column3','column4'),
('column1','column2','column3','column4'),
('column1','column2','column3','column4'),
('column1','column2','column3','column4');
JS fiddle demo
HTML:
<input id = "csv" type = "file" />
<div id="result"></div>
JS:
$('#csv').change(function(e) {
if ((window.FileReader) && (e.target.files != undefined)) {
var reader = new FileReader();
reader.onload = function(e) {
var lineSplit = e.target.result.split("\n");
var content = [];
for (var j = 1; j < lineSplit.length; j++) {
var fourColumnsData = lineSplit[j].split(',').slice(0, 4).join("','");
content.push(fourColumnsData);
}
var fileContent = content.join("')<br/>");
$('#result').html(fileContent);
};
reader.readAsText(e.target.files.item(0));
}
});
Try the following
$('#csv').change(function(e) {
if ((window.FileReader) && (e.target.files != undefined)) {
var reader = new FileReader();
reader.onload = function(e) {
var lineSplit = e.target.result.split("\n");
var content = [];
for (var j = 1; j < lineSplit.length; j++) {
if (lineSplit[j].trim().length > 0) {
var fourColumnsData = "('" + lineSplit[j].split(',').slice(0, 4).join("','") + "')";
content.push(fourColumnsData);
}
}
var fileContent = content.join(",");
$('#result').html(fileContent);
};
reader.readAsText(e.target.files.item(0));
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input id="csv" type="file" />
<div id="result"></div>
Related
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);
}
this code always return me '3' in alert.
I select two files together (ones .mp4 format and second ones .zip format)
function readFile(input) {
var counter = input.files.length;
for(x = 0; x<counter; x++){
if (input.files && input.files[x]) {
var extension = input.files[x].name.split('.').pop().toLowerCase();
var reader = new FileReader();
reader.onload = function (e) {
urlss = 1;
if(extension == 'mp4'){
urlss = 2;
}else{
urlss = 3;
}
alert(urlss);
};
reader.readAsDataURL(input.files[x]);
}
}
}
<input type="file" id="files" name="files[]" accept=".png, .jpg, .jpeg, .zip, .mp4" onchange="readFile(this);" multiple />
That is because of var hoisting
The onload function calling after the for was ended and extension == last file extension
Try replace var with const:
function readFile(input) {
var counter = input.files.length;
for(let x = 0; x < counter; x++){
if (input.files && input.files[x]) {
const extension = input.files[x].name.split('.').pop().toLowerCase();
const reader = new FileReader();
reader.onload = function (e) {
urlss = 1;
if(extension == 'mp4'){
urlss = 2;
}else{
urlss = 3;
}
alert(urlss);
};
reader.readAsDataURL(input.files[x]);
}
}
}
Update
Please check the Webber's comment below.
im using reader.onload event to get contents of csv file,
problem is the value displays in console.log() but not in DOM i.e via binding
dropped(event: UploadEvent) {
this.files = event.files;
console.log(this.files)
for (const droppedFile of event.files) {
// Is it a file?
if (droppedFile.fileEntry.isFile) {
const fileEntry = droppedFile.fileEntry as FileSystemFileEntry;
fileEntry.file((file: File) => {
// Here you can access the real file
console.log(droppedFile.relativePath, file);
const fileToRead = file;
const fileReader = new FileReader();
fileReader.onload = this.onFileLoad;
fileReader.readAsText(fileToRead);
console.log(this.tempval) /// undefined
});
}
}}
and onFileLoad function is as follows
onFileLoad(fileLoadedEvent) {
const textFromFileLoaded = fileLoadedEvent.target.result;
this.csvContent = textFromFileLoaded;
var allTextLines = this.csvContent.split(/\r\n|\n/);
var headers = allTextLines[0].split(',');
var lines = [];
for ( var i = 0; i < allTextLines.length; i++) {
// split content based on comma
var data = allTextLines[i].split(',');
if (data.length == headers.length) {
var tarr = [];
for ( var j = 0; j < headers.length; j++) {
tarr.push(data[j]);
}
lines.push(tarr);
}
}this.tempval = linesconsole.log(this.tempval) // printing value
};
unfortunately data inside this.tempval is not accessible anywhere
not in html DOM or inside dropped() funtion. except inside onFileLoad()
im just new to typescript
thanks in advance
I'm trying to upload an image using FileReader, It works fine in debug mode (when set breakpoint on the line this.name = Image.files[0].name;), but doesn't work if I deactivate breakpoint. testDetails.image gets set to empty string. I have tried setTimeout also, its also not working.
var fileByteArray = '';
const Image = this.AccUserImage.nativeElement;
if (Image.files && Image.files[0]) {
this.AccUserImageFile = Image.files[0];
}
var fileReader = new FileReader();
fileReader.onload = function (event) {
var imageData = fileReader.result;
var bytes = new Uint8Array(imageData);
//for (var i = 0; i < bytes.length; i++) {
for (var i = 0; i < bytes.length; ++i) {
fileByteArray += (String.fromCharCode(bytes[i]));
}
};
if (fileReader && Image.files && Image.files.length) {
fileReader.readAsArrayBuffer(Image.files[0]);
}
}
this.name = Image.files[0].name;
const ImageFile: File = this.AccUserImageFile;
let length = this.form.value.addresses.length;
this.testList = [];
for (let i = 0; i < length; i++) {
let testDetails = new testDto();
testDetails.image = btoa(fileByteArray);
}
Maybe the test should be at the end of the fileReader.load function because your test depends on fileReader.onload function to be finished at least once so fileByteArray is not undefined.
fileReader.onload = function (event) {
var imageData = fileReader.result;
var bytes = new Uint8Array(imageData);
for (var i = 0; i < bytes.length; ++i) {
fileByteArray += (String.fromCharCode(bytes[i]));
}
if (fileReader && Image.files && Image.files.length) {
fileReader.readAsArrayBuffer(Image.files[0]);
}
for (let i = 0; i < length; i++) {
let testDetails = new testDto();
testDetails.image = btoa(fileByteArray);
}
};
There were some problems in the current implementation, I am posting the working code below. The first problem was that I was using JavaScript style calling for onload function. The second problem was I have to put all the code inside onload function because readAsArrayBuffer is an async call.
var fileByteArray = '';
const Image = this.AccUserImage.nativeElement;
if (Image.files && Image.files[0]) {
this.AccUserImageFile = Image.files[0];
}
var fileReader = new FileReader();
fileReader.onload = (e) => {
var imageData = fileReader.result;
var bytes = new Uint8Array(imageData);
for (var i = 0; i < bytes.length; ++i) {
fileByteArray += (String.fromCharCode(bytes[i]));
}
this.name = Image.files[0].name;
const ImageFile: File = this.AccUserImageFile;
let length = this.form.value.addresses.length;
this.testList = [];
for (let i = 0; i < length; i++) {
testDetails.image = btoa(fileByteArray);
}
}
fileReader.readAsArrayBuffer(Image.files[0]);
I am trying to convert xls file into json I can convert it successfully but when I try to convert xlsx file into json I get an error as "Uncaught Header Signature: Expected d0cf11e0a1b11ae1 saw 504b030414000808".
Index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>XL to JSON</title>
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script src=" https://cdnjs.cloudflare.com/ajax/libs/xls/0.7.4-a/xls.js"></script>
</head>
<body>
<input type="file" id="my_file_input" />
<div id='my_file_output'></div>
<script>
var oFileIn;
$(function() {
oFileIn = document.getElementById('my_file_input');
if(oFileIn.addEventListener) {
oFileIn.addEventListener('change', filePicked, false);
}
});
function filePicked(oEvent) {
// Get The File From The Input
var oFile = oEvent.target.files[0];
var sFilename = oFile.name;
// Create A File Reader HTML5
var reader = new FileReader();
// Ready The Event For When A File Gets Selected
reader.onload = function(e) {
var data = e.target.result;
var cfb = XLS.CFB.read(data, {type: 'binary'});
var wb = XLS.parse_xlscfb(cfb);
// Loop Over Each Sheet
wb.SheetNames.forEach(function(sheetName) {
// Obtain The Current Row As CSV
var sCSV = XLS.utils.make_csv(wb.Sheets[sheetName]);
var oJS = XLS.utils.sheet_to_row_object_array(wb.Sheets[sheetName]);
$("#my_file_output").html(sCSV);
console.log(oJS)
});
};
// Tell JS To Start Reading The File.. You could delay this if desired
reader.readAsBinaryString(oFile);
}
</script>
</body>
</html>
Can any one please tell me how should I solve this.I am badly stucked in this problem.Thanks in advance.
You are using the xls library which does not support xlsx files. Please use the updated one:
https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.8.0/xlsx.js
You can find more details and documentation for this here.
It worked with this code:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>JS-XLSX Live Demo</title>
<style>
#b64data
{
width:100%;
}
</style>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
</head>
<body>
<b>JS-XLSX (XLSX/XLSB/XLSM/XLS/XML) Live Demo</b><br />
<div id="drop"></div>
<p><input type="file" name="xlfile" id="xlf" /></p>
<br />
<pre id="out"></pre>
<br />
<script src="shim.js"></script>
<script src="jszip.js"></script>
<script src="xlsx.js"></script>
<!-- uncomment the next line here and in xlsxworker.js for ODS support -->
<script src="ods.js"></script>
<script>
var X = XLSX;
var XW = {
/* worker message */
msg: 'xlsx',
/* worker scripts */
rABS: './xlsxworker2.js',
norABS: './xlsxworker1.js',
noxfer: './xlsxworker.js'
};
function fixdata(data)
{
var o = "", l = 0, w = 10240;
for(; l<data.byteLength/w; ++l) o+=String.fromCharCode.apply(null,new Uint8Array(data.slice(l*w,l*w+w)));
o+=String.fromCharCode.apply(null, new Uint8Array(data.slice(l*w)));
return o;
}
function get_radio_value( radioName )
{
var radios = document.getElementsByName( radioName );
for( var i = 0; i < radios.length; i++ )
{
if( radios[i].checked || radios.length === 1 )
{
return radios[i].value;
}
}
}
function to_json(workbook)
{
var result = {};
var result1 = [];
var array1 = [];
var arr =[];
workbook.SheetNames.forEach(function(sheetName)
{
var arr = X.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
var array_lenght = arr.length;
for(var i = 0 ;i<array_lenght;i++ )
{
if(arr.length > 0)
{
array1 = arr[i];
result = array1;
result1.push(array1);
}
}
});
var sub_key = [];
for(var ab in result1)
{
var key = ab;
var val = result1[ab];
for(var j in val)
{
sub_key.push(j);
console.log(sub_key);
}
if((sub_key.indexOf("Last Name") && sub_key.indexOf("Email") && sub_key.indexOf("First Name")) > -1)
{
return "right format";
}
else
{
return "wrong format";
}
}
}
function process_wb(wb)
{
var output = "";
switch(get_radio_value("format"))
{
case "json":
output = JSON.stringify(to_json(wb), 2, 2);
break;
default:
output = JSON.stringify(to_json(wb), 2, 2);
}
if(out.innerText === undefined) out.textContent = output;
else out.innerText = output;
if(typeof console !== 'undefined') console.log("output", new Date());
}
var xlf = document.getElementById('xlf');
function handleFile(e)
{
rABS = document.getElementsByName("userabs")[0];
use_worker = document.getElementsByName("useworker")[0];
var files = e.target.files;
var f = files[0];
{
var reader = new FileReader();
var name = f.name;
reader.onload = function(e)
{
if(typeof console !== 'undefined') console.log("onload", new Date());
var data = e.target.result;
if(use_worker)
{
xw(data, process_wb);
}
else
{
var wb;
if(rABS)
{
wb = X.read(data, {type: 'binary'});
} else
{
var arr = fixdata(data);
wb = X.read(btoa(arr), {type: 'base64'});
}
process_wb(wb);
}
};
if(rABS) reader.readAsBinaryString(f);
else reader.readAsArrayBuffer(f);
}
}
if(xlf.addEventListener) xlf.addEventListener('change', handleFile, false);
</script>
</body>
</html>
That answer might work, but I don't think its exactly what you are requesting. In fact, based on your question and the documentation for SheetJS/js-xlsx I would suggest something like this:
function filePicked(oEvent) {
// Get The File From The Input
var oFile = oEvent.target.files[0];
var sFilename = oFile.name;
// Create A File Reader HTML5
var reader = new FileReader();
// Ready The Event For When A File Gets Selected
reader.onload = function(e) {
var data = e.target.result;
var cfb = XLSX.read(data, {type: 'binary'});
console.log(cfb)
cfb.SheetNames.forEach(function(sheetName) {
// Obtain The Current Row As CSV
var sCSV = XLS.utils.make_csv(cfb.Sheets[sheetName]);
var oJS = XLS.utils.sheet_to_json(cfb.Sheets[sheetName]);
$("#my_file_output").html(sCSV);
console.log(oJS)
$scope.oJS = oJS
});
};
// Tell JS To Start Reading The File.. You could delay this if desired
reader.readAsBinaryString(oFile);}
I tried it and it works fine. And whats more important, its a real answer to your question.
<script type="text/javascript">
document.querySelector("html").classList.add('js');
var fileInput = document.querySelector( ".input-file" ),
button = document.querySelector( ".input-file-trigger"),
the_return = document.querySelector(".file-return");
button.addEventListener( "keydown", function( event ) {
if ( event.keyCode == 13 || event.keyCode == 32 ) {
fileInput.focus();
}
});
button.addEventListener( "click", function( event ) {
fileInput.focus();
return false;
});
fileInput.addEventListener( "change", function( event ) {
var oFile = event.target.files[0];
var sFilename = oFile.name;
var reader = new FileReader();
// Ready The Event For When A File Gets Selected
reader.onload = function(e) {
var data = e.target.result;
var cfb = XLSX.read(data, {type: 'binary'});
// Loop Over Each Sheet
cfb.SheetNames.forEach(function(sheetName) {
var sCSV = XLS.utils.make_csv(cfb.Sheets[sheetName]);
var oJS = XLS.utils.sheet_to_json(cfb.Sheets[sheetName]);
alert(oJS);
alert(sCSV);
});
};
// Tell JS To Start Reading The File.. You could delay this if desired
reader.readAsBinaryString(oFile);
});