Problems with formatting data coming from the html table to the xlsx file in filesaver.js - VueJs - vue.js

I'm using the Filesaver.js library to export an .xlsx file from a table I own. But I am getting some errors. See below:
Original table created using VueJs with Quasar Framework:
Generated .xlsx file:
Another case
Generated .xlsx file:
My code:
exportTable() {
let wb = XLSX.utils.table_to_book(document.querySelector('.q-table'), {
sheet: "Sheet JS",
})
let wbout = XLSX.write(wb, {
bookType: 'xlsx',
bookSST: true,
type: 'binary'
})
function s2ab(s) {
let buf = new ArrayBuffer(s.length)
let view = new Uint8Array(buf)
for (let i = 0; i < s.length; i++) view[i] = s.charCodeAt(i) & 0xFF
return buf
}
saveAs(new Blob([s2ab(wbout)], {
type: "text/plain;charset=utf-8"
}), 'test.xlsx')
Why is the format of the characters in the table not being kept when exporting the spreadsheet ?
Is my spreadsheet data not treated as a string?
I'm brazilian. Sorry for bad English (=

After a few days of looking for answers, I managed to solve my problem.
More precisely, just use {raw: true}. By doing this, the lib no longer formats the data, leaving it in the raw form that comes from HTML. Interestingly, I didn't find this in the documentation.
// import something here
import Vue from 'vue'
import XLSX from 'xlsx'
import {
saveAs
} from 'file-saver'
// Global Function
const exportExcel = (table) => {
let wb = XLSX.utils.table_to_book(table, {
sheet: "Sheet JS",
raw: true // Here
})
let wbout = XLSX.write(wb, {
bookType: 'xlsx',
bookSST: true,
type: 'binary'
})
function s2ab(s) {
let buf = new ArrayBuffer(s.length)
let view = new Uint8Array(buf)
for (let i = 0; i != s.length; i++) view[i] = s.charCodeAt(i) & 0xFF
return buf
}
saveAs(new Blob([s2ab(wbout)], {
type: "text/plain;charset=utf-8"
}), 'spreadsheet.xlsx')
}
Vue.prototype.$exportExcel = exportExcel;
// "async" is optional;
// more info on params: https://quasar.dev/quasar-cli/cli-documentation/boot-files#Anatomy-of-a-boot-file
//export default exportExcel
This link helped me

Related

Suitescript error: TypeError: Cannot set property "JSZipSync" of undefined

I have the following script where I am getting an error message:
org.mozilla.javascript.EcmaError: TypeError: Cannot set property
"JSZipSync" of undefined to
"org.mozilla.javascript.InterpretedFunction#6e57e155"
(/SuiteScripts/Suitelet to Excel.js#17(eval)#2)
According to Netsuite support, there are no issues with the script and they are not getting this error message
/**
*#NApiVersion 2.x
*#NScriptType Suitelet
*/
define(["N/search", "N/file", "N/https"], function (search, file, https) {
function onRequest(context) {
// Load the xlsx library from the CDN
var response = https.get({
url: "https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.17.0/xlsx.full.min.js",
});
var script = response.body;
eval(script);
// Replace this with the ID of the saved search you want to run
var searchId = "customsearch_my_saved_search";
// Run the search and get the results
var searchResult = search.load({
id: searchId,
});
var searchRows = searchResult.run().getRange({
start: 0,
end: 1000,
});
// Create an array to hold the data for the Excel file
var data = [];
// Add the column names as the first row
var columnNames = [];
searchResult.columns.forEach(function (column) {
columnNames.push(column.label);
});
data.push(columnNames);
// Add the search results to the data array
searchRows.forEach(function (row) {
var rowData = [];
searchResult.columns.forEach(function (column) {
rowData.push(
row.getValue({
name: column.name,
})
);
});
data.push(rowData);
});
// Create the Excel file
var ws = XLSX.utils.aoa_to_sheet(data);
var wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
var binaryData = XLSX.write(wb, {
type: "binary",
bookType: "xlsx",
});
var fileName = "search_results.xlsx";
var folderId = -4; // -4 represents the "Home" folder in the file cabinet
var file = file.create({
name: fileName,
fileType: file.Type.EXCEL,
contents: binaryData,
folder: folderId,
});
// Send the file as a response to the user
context.response.writeFile({
file: file,
isInline: true,
});
});
}
return {
onRequest: onRequest,
};
});
I can't tell where I am going wrong?
The JSZipSync is a function in the xlsx.full.min.js library which I believe I have loaded correctly.
I have also tried storing this file in the filing cabinet and referencing that instead of a link to the CDN website.
The same error message is generated in both cases

How to remove time component from date fields while exporting to excel using sheetjs

I am able to export a list of JSON objects to an excel file using sheetjs in angular. One of the requirements is, user should be able to sort and filter the date fields like below.
But as you can see, along with the date part, the time part also comes while filtering. Is there a way, I can remove the time part and still be able to do the filtering like above?
Here is my code.
exportToExcel(arrData: any[], fileName: string, formattingData: ExcelFormattingData = undefined) {
const worksheet: XLSX.WorkSheet = XLSX.utils.json_to_sheet(arrData, {cellDates: true, dateNF: this.userAuthToken.dateFormat});
if(formattingData != null) {
const range = XLSX.utils.decode_range(worksheet['!ref']);
for (let j = range.s.c; j <= range.e.c; j++) {
let ref_columnHeader = XLSX.utils.encode_cell({r:range.s.r, c:j});
let columnName = worksheet[ref_columnHeader].v;
if(formattingData.Values.includes(columnName)){
for(let i = range.s.r + 1; i <= range.e.r; ++i) {
let ref = XLSX.utils.encode_cell({r:i, c:j});
if(worksheet[ref] != null) {
worksheet[ref].t = 'd';
worksheet[ref].z = formattingData.Format;
}
}
}
}
}
const workbook: XLSX.WorkBook = { Sheets: { 'data': worksheet }, SheetNames: ['data'] };
const excelBuffer: any = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
const blob = new Blob([excelBuffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8' });
FileSaver.saveAs(blob, fileName);
}

while reading Excel data using XLSX.read method , data contains Unicode character

excel file contains the data "TEST_XD715_DATA" in one column. when trying to read the excel data using XLSX.read method , getting data as "TEST휕DATA"
Note:
XD715 replaced with the unicode symbol - 휕
CODE:
HTML CODE:
<input #myInput type="file" (change)="incomingfile($event)" placeholder="Upload file"
accept=".xls,.xlsx,.csv">
Typescript File:
incomingfile(event) {
this.file = event.target.files[0];
let fileReader = new FileReader();
fileReader.onload = async (event) => {
var workbook = XLSX.read(fileReader.result, { type: "binary" });
var worksheet = workbook.Sheets[workbook.SheetNames[0]];
this.excelObj = XLSX.utils.sheet_to_json(worksheet, { defval: "" });
......
......
}
fileReader.readAsBinaryString(this.file);
}

Convert RTF (Rich Text Format) code into plain text in Excel

I'm exporting a database query as Excel and I am getting rows with RTF formatting.
How can I convert these fields into plain text? I've found answers that are pretty old, so I was wondering if anyone knows a way.
The .Net Framework RichTextBox class can perform the conversion. Fortunately, this class has the ComVisibleAttribute set, so it can be used from VBA without much difficulty.
I had to create a .tlb file to Reference. In the
%SYSTEMROOT%\Microsoft.NET\Framework\currentver\
directory, run the command
regasm /codebase system.windows.forms.dll
to create the system.windows.forms.tlb file. I already had this .tlb file on my system, but I had to recreate it using this command to be able to create a .Net System.Windows.Forms RichTextBox object successfully in VBA.
With the new .tlb file created, in VBA link it to your project via Tools->References in the VBA IDE.
I wrote this test code in Access to demonstrate the solution.
Dim rtfSample As String
rtfSample = "{\rtf1\ansi\deflang1033\ftnbj\uc1 {\fonttbl{\f0 \froman \fcharset0 Times New Roman;}{\f1 \fswiss \fcharset0 Segoe UI;}} {\colortbl ;\red255\green255\blue255 ;} {\stylesheet{\fs22\cf0\cb1 Normal;}{\cs1\cf0\cb1 Default Paragraph Font;}} \paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\headery720\footery720\deftab720\formshade\aendnotes\aftnnrlc\pgbrdrhead\pgbrdrfoot \sectd\pgwsxn12240\pghsxn15840\marglsxn1440\margrsxn1440\margtsxn1440\margbsxn1440\headery720\footery720\sbkpage\pgnstarts1\pgncont\pgndec \plain\plain\f1\fs22\lang1033\f1 hello question stem\plain\f1\fs22\par}"
Dim miracle As System_Windows_Forms.RichTextBox
Set miracle = New System_Windows_Forms.RichTextBox
With miracle
.RTF = rtfSample
RTFExtractPlainText = .TEXT
End With
MsgBox RTFExtractPlainText(rtfSample)
With the result
hello question stem
I'd assume re-creating the .tlb file in the \Framework64\ directory would be needed on 64-bit Windows with 64-bit Office. I am running 64-bit Win10 with 32-bit Office 2013, so I had to have a 32-bit .tlb file.
Another alternative can be using Microsoft Rich Textbox Control (but can't test it on x64 Office)
Sub rtfToText()
With CreateObject("RICHTEXT.RichtextCtrl") ' or add reference to Microsoft Rich Textbox Control for early binding and With New RichTextLib.RichTextBox
.SelStart = 0 ' needs to be selected
.TextRTF = Join(Application.Transpose(Cells.CurrentRegion.Columns(1)))
[C1] = .Text ' set the destination cell here
' or if you want them in separate cells:
a = Split(.Text, vbNewLine)
Range("C3").Resize(UBound(a) + 1) = Application.Transpose(a)
End With
End Sub
I'm revisiting this question to provide 2 javascript solutions, rather than a .NET one.
Approach 1
const parseRTF = require("rtf-parser");
let rtf = `{\\rtf1\\ansi\\deff0\\nouicompat{\\fonttbl{\\f0\\fnil\\fcharset0 Calibri;}{\\f1\\fnil\\fcharset204 Calibri;}{\\f2\\fnil Calibri;}} {\\colortbl ;\\red0\\green0\\blue0;} {\\*\\generator Riched20 10.0.19041}\\viewkind4\\uc1 \\pard\\cf1\\f0\\fs18\\lang1033 WEB1616 \\f1\\lang1071\\'ef\\'eb\\'e0\\'f2\\'e5\\'ed\\'ee \\'f1\\'ee \\'ea\\'e0\\'f0\\'f2\\'e8\\'f7\\'ea\\'e0\\par \\'ca\\'f0\\'e8\\'f1\\'f2\\'e8\\'ed\\'e0 \\'c3\\'ee\\'eb\\'e0\\'e1\\'ee\\'f1\\'ea\\'e0 077640615\\par \\'c2\\'e0\\'f0\\'f8\\'e0\\'e2\\'f1\\'ea\\'e0 6\\'e0\\par 1000 \\'d1\\'ea\\'ee\\'ef\\'bc\\'e5\\f2\\lang1033\\par } `;
function convertRTFtoPlainText(rtf) {
return new Promise((resolve, reject) => {
parseRTF.string(rtf, (err, doc) => {
if (err) {
reject(err);
}
let string = "";
doc.content.forEach((item) => {
if (item.content) {
item.content.forEach((span) => {
string += span.value;
});
} else {
string += item.value;
}
});
resolve(string.trim());
});
});
}
(async () => {
let value = await convertRTFtoPlainText(rtf);
console.log(value);
})();
Approach 2
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
function stringToArrayBuffer(string) {
if (string == null) return;
let buffer = new ArrayBuffer(string.length);
let bufferView = new Uint8Array(buffer);
for (let i = 0; i < string.length; i++) {
bufferView[i] = string.charCodeAt(i);
}
return buffer;
}
// callback = function to run after the DOM has rendered, defined when calling runRtfjs
function runRtfjs(rtf, callback, errorCallback) {
const virtualConsole = new jsdom.VirtualConsole();
virtualConsole.sendTo(console);
let dom = new JSDOM(
`
<script src="./node_modules/rtf.js/dist/RTFJS.bundle.js"></script>
<script>
RTFJS.loggingEnabled(false);
try {
const doc = new RTFJS.Document(rtfFile);
const meta = doc.metadata();
doc
.render()
.then(function(htmlElements) {
const div = document.createElement("div");
div.append(...htmlElements);
// window.done(meta, div.innerHTML);
// window.done(meta, div.innerText);
window.done(meta, div.textContent); // pass the data to the callback
}).catch(error => window.onerror(error))
} catch (error){
window.onerror(error)
}
</script>
`,
{
resources: "usable",
runScripts: "dangerously",
url: "file://" + __dirname + "/",
virtualConsole,
beforeParse(window) {
window.rtfFile = stringToArrayBuffer(rtf);
window.done = function (meta, html) {
callback(meta, html); // call the callback
};
window.onerror = function (error) {
errorCallback(error);
};
},
}
);
}
let rtf = `{\\rtf1\\ansi\\deff0\\nouicompat{\\fonttbl{\\f0\\fnil\\fcharset0 Calibri;}{\\f1\\fnil\\fcharset204 Calibri;}{\\f2\\fnil Calibri;}} {\\colortbl ;\\red0\\green0\\blue0;} {\\*\\generator Riched20 10.0.19041}\\viewkind4\\uc1 \\pard\\cf1\\f0\\fs18\\lang1033 WEB1616 \\f1\\lang1071\\'ef\\'eb\\'e0\\'f2\\'e5\\'ed\\'ee \\'f1\\'ee \\'ea\\'e0\\'f0\\'f2\\'e8\\'f7\\'ea\\'e0\\par \\'ca\\'f0\\'e8\\'f1\\'f2\\'e8\\'ed\\'e0 \\'c3\\'ee\\'eb\\'e0\\'e1\\'ee\\'f1\\'ea\\'e0 077640615\\par \\'c2\\'e0\\'f0\\'f8\\'e0\\'e2\\'f1\\'ea\\'e0 6\\'e0\\par 1000 \\'d1\\'ea\\'ee\\'ef\\'bc\\'e5\\f2\\lang1033\\par } `;
runRtfjs(
rtf,
(meta, html) => {
console.log(html);
},
(error) => console.error(error)
);

Win 8 Apps : saving and retrieving data in roamingfolder

I'm trying to store few user data into a roamingFolder method/property of Windows Storage in an app using JavaScript. I'm following a sample code from the Dev Center, but no success. My code snippet is as follows : (OR SkyDrive link for the full project : https://skydrive.live.com/redir?resid=F4CAEFCD620982EB!105&authkey=!AE-ziM-BLJuYj7A )
filesReadCounter: function() {
roamingFolder.getFileAsync(filename)
.then(function (filename) {
return Windows.Storage.FileIO.readTextAsync(filename);
}).done(function (data) {
var dataToRead = JSON.parse(data);
var dataNumber = dataToRead.count;
var message = "Your Saved Conversions";
//for (var i = 0; i < dataNumber; i++) {
message += dataToRead.result;
document.getElementById("savedOutput1").innerText = message;
//}
//counter = parseInt(text);
//document.getElementById("savedOutput2").innerText = dataToRead.counter;
}, function () {
// getFileAsync or readTextAsync failed.
//document.getElementById("savedOutput2").innerText = "Counter: <not found>";
});
},
filesDisplayOutput: function () {
this.filesReadCounter();
}
I'm calling filesDisplayOutput function inside ready method of navigator template's item.js file, to retrieve last session's data. But it always shows blank. I want to save upto 5 data a user may need to save.
I had some trouble running your code as is, but that's tangential to the question. Bottom line, you're not actually reading the file. Note this code, there's no then or done to execute when the promise is fulfilled.
return Windows.Storage.FileIO.readTextAsync(filename);
I hacked this in your example solution and it's working... typical caveats of this is not production code :)
filesReadCounter: function () {
roamingFolder.getFileAsync(filename).then(
function (filename) {
Windows.Storage.FileIO.readTextAsync(filename).done(
function (data) {
var dataToRead = JSON.parse(data);
var dataNumber = dataToRead.count;
var message = "Your Saved Conversions";
//for (var i = 0; i < dataNumber; i++) {
message += dataToRead.result;
document.getElementById("savedOutput1").innerText = message;
//}
//counter = parseInt(text);
//document.getElementById("savedOutput2").innerText = dataToRead.counter;
}, function () {
// readTextAsync failed.
//document.getElementById("savedOutput2").innerText = "Counter: <not found>";
});
},
function () {
// getFileAsync failed
})
},