I am using ClosedXML to export to excel which is working fine but I need to hide some columns if rows are empty. I am doing below but it is not working
var dt = new DataTable("Grid");
dt.Columns.AddRange(new[]
{
var dt = new DataTable("Grid");
dt.Columns.AddRange(new[]
{
new DataColumn("Id"),
new DataColumn("forms"),
new DataColumn("Number"),
new DataColumn("Employees"),
});
var test = data.employee.Select(f => f.name);
foreach( var h in test)
{
foreach(var n in dt.Columns)
{
if( n.lastname==null)
{
dt.Columns.Remove("Employees");
}
}
}
I have got it working by myself.
if( n.lastname==null)
{
if (dt.Columns.Contains("Employees"))
{
dt.Columns.Remove("Employees");
}
dt.AcceptChanges();
}
Related
I have an Excel file with the following content:
Inside my component.ts, I extract the Excel's content as follow:
var testUrl= "excel.xlsx";
var oReq = new XMLHttpRequest();
oReq.open("GET", testUrl, true);
oReq.responseType = "arraybuffer";
oReq.onload = function(e) {
var arraybuffer = oReq.response;
var data = new Uint8Array(arraybuffer);
var arr = new Array();
for(var i = 0; i != data.length; ++i){
arr[i] = String.fromCharCode(data[i]);
}
var bstr = arr.join("");
var workbook = XLSX.read(bstr, {type:"binary"});
var first_sheet_name = workbook.SheetNames[0];
var worksheet = workbook.Sheets[first_sheet_name];
var json = XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]], {header:1, raw:true});
var jsonOut = JSON.stringify(json);
console.log("test"+jsonOut);
}
oReq.onerror = function(e) {
console.log(e);
}
oReq.send();
XLSX.utils.sheet_to_json will format JSON as follow:
However, I would like the JSON to be as follow:
Most probably I would need to manually create the JSON, but can anyone help me point to the direction on how I can accomplish this?
In your case we need to modify the JSON data by looping over XLSX.utils.sheet_to_json JSON object:
// This object will contain the data in the format we want
var finalObj = { "object": []};
// Variables to track where to insert the data
var locIndex, firstCondIndex, secondCondIndex,
lockey, firstCondKey, secondCondkey;
// We need to initialize all indexes to -1 so that on first time we can get 0, as arrays start with 0 in javascript
locIndex = -1;
// here obj is XLSX.utils.sheet_to_json
obj.object.map((value, index) => {
// we don't want to consider name of columns which is first element of array
if(!index) return;
// Go inside only if not null
if(value[0]) {
// For Location
finalObj.object.push(createObj(value[0]));
locIndex++;
// We also need to store key names to push it's children
lockey = value[0];
firstCondIndex = -1;
}
if(value[1]) {
// For First Condition
finalObj.object[locIndex][lockey].push(createObj(value[1]));
firstCondIndex++;
firstCondKey = value[1];
secondCondIndex = -1;
}
if(value[2]) {
// For Second Condition
finalObj.object[locIndex][lockey][firstCondIndex][firstCondKey].push(createObj(value[2]));
secondCondIndex++;
secondCondkey = value[2];
}
if(value[3]) {
// For Products
// We just push the string
finalObj.object[locIndex][lockey][firstCondIndex][firstCondKey][secondCondIndex][secondCondkey].push(value[3]);
}
});
function createObj(val) {
// We need to initialize blank array so we can push the children of that element later on
var obj = {};
obj[val] = [];
return obj;
}
console.log(finalObj);
So I need to display a text once an action is performed but even though I tried to do so by using dynamic text and labels, I didn't manage to finish my programming due to errors:
var group:RadioButtonGroup= new RadioButtonGroup ("Question1");
var group2:RadioButtonGroup= new RadioButtonGroup ("Question2");
var group3:RadioButtonGroup= new RadioButtonGroup ("Question3");
var group4:RadioButtonGroup= new RadioButtonGroup ("Question4");
var group5:RadioButtonGroup= new RadioButtonGroup ("Question5");
var counterT:int;
var counterF:int;
submit.buttonMode=true;
counterT=0;
counterF=0;
t1.group = group;
f1.group = group;
t2.group=group2;
f2.group=group2;
t3.group=group3;
f3.group=group3;
t4.group=group4;
f4.group=group4;
t5.group=group5;
f5.group=group5;
submit.label="Submit";
submit.addEventListener(MouseEvent.CLICK,submitanswer);
function submitanswer (event:MouseEvent): void {
if (group.selection == t1) {
counterT==counterT+1
}
else
if (group.selection==f1) {
counterF==counterF+1;
}
}
if (group2.selection ==t2) {
counterT==counterT+1
}
else
if (group2.selection==f2) {
counterF==counterF+1
}
if (group3.selection ==t3) {
counterT==counterT+1
}
else
if (group3.selection==f3) {
counterF==counterF+1
}
if (group4.selection ==t4) {
counterT==counterT+1
}
else
if (group4.selection==f4) {
counterF==counterF+1
}
if (group5.selection ==t5) {
counterT==counterT+1
}
else
if (group5.selection==f5) {
counterF==counterF+1
}
The first thing I see is that you are using the == to set a value. You need to use = when setting values. So like this:
if (x == y) {
counter = counter + 1;
}
or you can just use counter++ like this
if (x == y) {
counter++;
}
In ES6's Set next Property is available like
var mySet = new Set();
mySet.add("foobar");
mySet.add(1);
mySet.add("baz");
var setIter = mySet.entries();
console.log(setIter.next().value); // ["foobar", "foobar"]
How to navigate to the previous property, Is something like below is available?
console.log(setIter.previous().value);
Iterators do not have a previous function. You can however iterate using for..of instead and keep track of the previous value:
var mySet = new Set();
mySet.add("foobar");
mySet.add(1);
mySet.add("baz");
let previous;
for(const current of mySet.entries()) {
console.log(previous, current);
previous = current;
}
Then you can wrap in a function which returns a generator like so:
var mySet = new Set();
mySet.add("foobar");
mySet.add(1);
mySet.add("baz");
const previousNextIterator = theSet => {
return {
previous: undefined,
*[Symbol.iterator]() {
for(const e of theSet.entries()) {
yield e;
this.previous = e;
}
}
};
};
const iter = previousNextIterator(mySet);
for(const current of iter) {
console.log(current, iter.previous);
}
From this tutorial i've got a good result printing , and this tutorial on how to print multiple pages from html, i'm trying to do the same with a Datagrid.
my problem is when the number of rows exceed the height of Datagrid so i tried to break it down to several pages, this is my code:
protected function button3_clickHandler(event:MouseEvent):void
{
var success:Boolean = printJob.start2(disablePageRange.selected ? this.printUIOptions : null, false);
var pjo:PrintJobOptions = new PrintJobOptions;
if (methodBitmap.selected){
pjo.printMethod = PrintMethod.BITMAP;
}
else if (methodVector.selected){
pjo.printMethod = PrintMethod.VECTOR;
}
else{
pjo.printMethod = PrintMethod.AUTO;
}
if (printJob.maxPixelsPerInch > 600){
pjo.pixelsPerInch = 600;
}
updateForm();
updateThePage();
updateTheWindow();
//--------------------------------------
var b:int = 0;
var H:int = myDataGrid.rowHeight *2;
for each (var item:Object in meme as ArrayCollection ){
if (H > myDataGrid.height){
myDataGrid.dataProvider = arlst;
printJob.addPage(thePrintableArea, null, pjo);
arlst.removeAll();
H = myDataGrid.rowHeight *2;
b++;
//Alert.show(b.toString());
}else{
arlst.addItem(item);
H += myDataGrid.rowHeight;
}
}
printJob.send();
}
The result: i get the first page but the rest are just blank Datagrid:
This answers: http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7c7e.html
Summary:
create external Itemrenderer and populate the data to it.
I want the script to show max 26 letters and if there is more I want it to make (...) <-- so that you can se there is more letters in the link.
First I put a bit of a script I have for another site containing a variable to do that, however it doesn't work in RSS:
{
temp.Add(titel);
count++;
string titel_kort = titel;
if (titel.Length > 26)
{
titel_kort = titel.Substring(0, 26) + "...";
}
}
And this is the script I want to integrate to:
#using System.Xml.XPath;
#using System.Xml;
#{
try
{
XmlTextReader udBrudRSS = new XmlTextReader("http://tidende.dk/rss.aspx");
XmlDocument doc = new XmlDocument();
doc.Load(udBrudRSS);
XmlNodeList rssItems = doc.SelectNodes("//item");
var count = 0;
foreach (XmlNode node in rssItems )
{
count++;
if (count > 3) { break; }
<div class="nyhedlink">- #node["title"].InnerText</div>
}
}
catch {}
}
You could something like this :
using (var webclient = new WebClient())
{
var data = webclient.DownloadData("http://tidende.dk/rss.aspx");
var oReader = new XmlTextReader(new MemoryStream(data));
var xml = XDocument.Load(oReader);
var values = xml.XPathSelectElements("//item").Take(3).Select(p => new
{
Link = p.XPathSelectElement("//link").Value,
Title = (p.XPathSelectElement("./title").Value.Length > 26) ?
p.XPathSelectElement("./title").Value.Substring(0, 26).Trim() + "..." :
p.XPathSelectElement("./title").Value.Trim()
});
foreach (var item in values)
{
<div class="nyhedlink">- #item.Title</div>
}
}
Sometimes is better use WebClient to make the petition instead of XmlTextReader see this question for a good explanation.