Spotfire Webplayer crosstable export with title - export-to-excel

I Have requirement to export Crosstable data along with Header in Spotfire.
1) First i tried direct excel export with location from temp folder or direct location like C:\Export\Text.xls. these are working perfect in Spotfire client. But in webplayer it is not working. It is throwing Access issue to the folder.
2) Secondly i tried, With help of other forums i developed a code to convert Crosstable to text area through Iron python script and HTML to excel through JAVA script. This is working perfect in webplayer chrome browser. But the issue here is it is working perfectly for the small data. but i have to export around 10 MB. so it hung in both client and webplayer.
Can anyone help me to fix this.
Script 1: Cross table to HTML and then to javascript for download. This script hangs due to size of the data. When i use small data it works perfect in chrome.
from Spotfire.Dxp.Application.Visuals import TablePlot, HtmlTextArea,
CrossTablePlot
ta = visTA.As[HtmlTextArea]()
from System.IO import Path, StreamWriter
from System.Text import StringBuilder
from System.IO import *
tempFilename = MemoryStream();
tp = visDT.As[CrossTablePlot]()
writer = StreamWriter(tempFilename)
tp.ExportText(writer)
tempFilename.Seek(0,SeekOrigin.Begin);
#Build the table
sb = StringBuilder()
#Open the temp file for reading
f = open(tempFilename)
#add some scripting magic from CDN
html = ""
#build the html table
html += " <TABLE id='myTable'>\n"
html += "<THEAD>"
html += " <TR><TH>"
html += "Performance Attribution"
html += " </TH></TR> <TR><TH>"
html += Heading2
html += " </TH></TR> <TR><TH>"
html += Heading6
html += " </TH></TR> <TR><TH>"
html += Heading3
html += " </TH></TR> <TR><TH>"
html += " </TH></TR> <TR><TH><Font Size=3><B>"
html += Heading4
html += "</TD><TD></TD><TD></TD><TD>"
html += Heading5
html += "</TD><TD></TD><TD></TD><TD>"
html += "Attribution Analysis"
html += "</TD><TD></TD></B></Font></TH></TR>"
html += " <TR><TH>"
html += " </TH><TH>".join(f.readline().split("\t")).strip()
html += " </TH></TR>"
html += "</THEAD>\n"
html += "<TBODY>\n"
for line in f:
html += "<TR><TD>"
html += "</TD><TD>".join(line.split("\t")).strip()
html += "</TD></TR>\n"
f.close()
html += "</TBODY>\n"
html += "</TABLE>\n"
ta.HtmlContent = html
Script to Export from Text Area
==============================================================
jQuery.fn.fnExcelReport = function(options)
{
var options = jQuery.extend({
separator: ',',
header: [],
headerSelector: 'th',
columnSelector: 'td',
delivery: 'popup', // popup, value, download
// filename: 'powered_by_sinri.csv', // filename to download
transform_gt_lt: true // make > and < to > and <
},
options);
var tab_text="<table border='2px'><tr bgcolor='#87AFC6'>";
var textRange; var j=0;
//tab = $(this); // id of table
tab = document.getElementById('myTable');
for(j = 0 ; j < tab.rows.length ; j++)
{
tab_text=tab_text+tab.rows[j].innerHTML+"</tr>";
//tab_text=tab_text+"</tr>";
}
tab_text=tab_text+"</table>";
var ua = window.navigator.userAgent;
var msie = ua.indexOf("MSIE ");
sa = window.open('data:application/vnd.ms-excel,' +
encodeURIComponent(tab_text));
return (sa);
}
$(document).ready(function () {
$('table').each(function () {
var $table = $(this);
var $button = $("<button type='button'>");
$button.text("Download");
$button.insertBefore($table);
$button.click(function () {
var csv = $table.fnExcelReport({
delivery: 'value'
});
});
});
})
#Script 2: This script is working in client and not in web browsers.
from System.IO import *
from System import Environment, Threading
username = Threading.Thread.CurrentPrincipal.Identity.Name
import clr
clr.AddReference("System.Windows.Forms")
from Spotfire.Dxp.Data.Export import DataWriterTypeIdentifiers
from System.Windows.Forms import SaveFileDialog
from System.Diagnostics import Process, ProcessStartInfo
from Spotfire.Dxp.Application.Visuals import VisualContent
vc=Visuals.As[VisualContent]() #Visuals = Script parameter for Table/Cross
Table visualization
memStream = MemoryStream();
writer =
Document.Data.CreateDataWriter(DataWriterTypeIdentifiers.ExcelXlsDataWriter);
sWriter = StreamWriter(memStream);
#Exporting the data to Memory Stream
vc.ExportText(sWriter); #exports data in tab separated text
sReader = StreamReader(memStream);
memStream.Seek(0, SeekOrigin.Begin);
tempFolder = Path.GetTempPath()
Filenm = "Fixed_Income_Performce_Attribution.csv";
str1='\\'
print str1
newtemp = tempFolder
print newtemp
filename=newtemp+Filenm
print filename
f=open(filename,"w+")
counter=0
j=0
str1=''
f.write("Percent of Total Holdings"+'\n')
f.write(Heading2+'\n')
f.write(Heading3+'\n')
f.write(Heading6+'\n')
f.write('\n'+'\n')
while (sReader.Peek()>=0):
line=[]
counter=counter+1 #counts the number of rows in dataset
a=sReader.ReadLine()
lines=a.split("\t")
for elem in lines:
j=j+1 # counts the number of columns in dataset
#print elem
if str(elem).find(",")<>-1:
elem='"'+elem+'"' # escaping comma already present in string
line.append(elem)
str1 = ','.join(str(e) for e in line)
f.write(str1+'\n')
f.close();
MemoryStream.Dispose(memStream);
sReader.Close()
Process.Start(filename)
Thanks
Venkatesh

For your first query (downloading to C:\Export\Text.xls); when this script runs on the web player, the files will be generated on the node manager machine (since this is where the IP script is executed).
You could output the files to a network/ shared drive, perhaps? You would need to add the network drive path to the allowed path section of Spotfire.Dxp.Worker.Host.exe.config and ensure it can be accessed by the node manager.

Related

Split window java script for InDesign

Does anyone know of or can help me figure out how to create a script for InDesign to do the Split Screen command, this is found under menu selection Window > Arrange > Split Window. Thank you!
Basically this should work:
app.menuActions.item("$ID/Split Window").invoke()
But actually it sometimes works and sometimes doesn't. I can't tell why.
It works more or less stable as a toggle split/unsplit this way:
try {
app.menuActions.item("$ID/Split Window").invoke()
} catch(e) {
app.menuActions.item("$ID/Unsplit Window").invoke()
}
Probably there is some property, which you can read and run split command only if the window is not splitted already. I don't know.
Update
The list of 'menuActions' you can get with this script:
var list = "ID\tName\tArea\n";
var i = 0;
for (var i=0; i<app.menuActions.length; i++) {
var m = app.menuActions[i];
list += m.id + "\t" + m.name + "\t" + m.area + "\n";
}
f = File("menu_actions.txt");
f.encoding = "UTF-8";
f.open("w");
f.write(list);
f.close();
f.execute(); // to open the txt file immediately
\\ alert(i + " actions wese saved to " + f.fsName);
All credits to Kasyan Servetsky: http://kasyan.ho.ua/tips/indesign_script/all/open_menu_item.html

how can I extract text from indd files or indesign files using python programs?

I need to create an api where user will provide indesign file and I need to extract text from it.
Basically it can be done this way:
from win32com.client import Dispatch
app = Dispatch('InDesign.Application.CS6')
doc = app.Open(r"d:\text.indd")
contents = ""
for story in doc.stories: contents += story.contents + "\n"
f = open(r"d:\text.txt", "w", encoding="utf8")
f.write(contents)
f.close()
doc.Close()
But perhaps there can be glitches with special symbols. I believe it makes sense to use the native Javascript Extendscript for this task. Something like this:
var doc = app.open(File("d:/text.indd"));
var stories = doc.stories.everyItem().getElements();
var contents = "";
for (var i=0; i<stories.length; i++) contents += stories[i].contents + "\n";
var file = File("d:/text.txt");
file.open("w");
file.write(contents);
file.close();
doc.close();

Why is this getting the same row twice in second loop?

The code below runs with no apparent errors, but despite I've looked for all possible causes I could think of, I couldn't find the reason why it gets the correct row iterated, marks it as processed ("Sim), and from the 2º iteration on, it gets the new row, but repeats the others already iterated over.
function formToData() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var ss = sheet.getSheetByName("Form Responses 1");
var targetSheet = sheet.getSheetByName("Cadastro de Cliente");
var StartRow = 2;
var RowRange = ss.getLastRow() - StartRow + 1;
var WholeRange = ss.getRange(StartRow, 1, RowRange, 30);
var AllValues = WholeRange.getValues();
var message = "";
for (var i = 0; i < AllValues.length; i++) {
var currentRow = AllValues[i];
//if row has been sent, then continue to next iteration
if (currentRow[0] != "" && currentRow[29] != "Sim") {
//set the row to look at
var setRow = parseInt(i) + StartRow;
var data = currentRow[0];
var dataFormatted = Utilities.formatDate(data, SpreadsheetApp.getActive().getSpreadsheetTimeZone(), "dd/MM/yyyy', às 'HH:mm") + "hs";
//set HTML template for information
message +=
"<p><b>Data: </b>" + dataFormatted + "</p>" +
"<p><b>Unidade: </b>" + currentRow[1] + "</p>"
//mark row as "sent"
ss.getRange(setRow, 30).setValue("Sim");
var values = targetSheet.getRange("A:A").getValues();
var maxIndex = values.reduce(function (maxIndex, row, index) {
return row[0] === "" ? maxIndex : index;
}, 0);
targetSheet.getRange(maxIndex + 2, 1, 1, 30)
.setNumberFormat("#")
.setValues([currentRow]);
var sendTo = "email";
var subject = "Cadastro de cliente novo";
if (message) {
MailApp.sendEmail({
to: sendTo,
subject: subject,
name: "Comercial - Emape",
htmlBody: message,
});
}
}
}//For loop closes
}
I'd appreaciate if you could help me find the flaw.
I tried to replicate this behavior, however, on a static sheet the script performs as expected:
Set unmarked rows in column 30 as 'Sim'.
Copy these rows to a separate sheet starting from the first empty row (or whichever row that Column A is empty).
Given the names of the functions and the sheets, this may be a Sheet generated by a Google Form. These sheets are dynamic, and there is a possibility that the contents may change while your script is running, especially if users are allowed to edit responses.
As a workaround, I suggest to lock the form before running the script:
Also, check the contents of the sheet and form for any possibility that the "Sim" mark might be overwritten by new or edited form data, maybe the sheet is inserting 30 columns instead of 29 or less.

Google appscipt - Exporting multiple PDF with a for loop, using a sheet as a template, unexpected result

I'm trying to automate the pdf export of a sheet ('BL') which is filled depending on a cell value grabbed on a variable list on sheet 'EiBLdata' by 'i' on each loop.
It seems to work... more or less.
Instead of having 1st pdf with 1st value,
2nd pdf with 2nd value,
3rd pdf with 3rd value etc.
I get 1st pdf with 1st value,
2nd pdf with 1st value,
3rd pdf with 2nd value etc.
In the end only the 1st pdf has the right name, there is a shift in all the others and the last value isn't exported.
I'm quite a newbie with JavaScript and I admit there is a lot of copy/paste in my code, adapted to my purpose. I can't find what I'm doing wrong.
function printSelectedRange() {
var nomfeuille = "EiBLData"
var nomBL = "BL"
var cc = SpreadsheetApp.getActiveSpreadsheet();
var feuille = cc.getSheetByName(nomfeuille);
var BL = cc.getSheetByName(nomBL);
var tr = BL.getRange('B2').getValue();
var plage = feuille.getRange('A1:A15').getValues();
var cell0 = feuille.getRange(1,1).getValue();
BL.getRange('B2').setValue(cell0);
for (var i = 1; i <= 16; i++) {
var cell = feuille.getRange(i,1).getValue();
if (cell > 0) {
BL.getRange('B2').setValue(cell)
var sheetName = "BL";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sheetName);
var ssUrl = ss.getUrl();
var sheetId= sheet.getSheetId();
var url = ssUrl.replace(/\/edit.*$/,'')
+ '/export?exportformat=pdf&format=pdf'
+ '&size=A6'
+ '&portrait=false'
+ '&fitw=false'
+ '&scale=4'
+ '&top_margin=0.35'
+ '&bottom_margin=0.00'
+ '&left_margin=0.35'
+ '&right_margin=0.0'
+ '&sheetnames=false'
+ '&printtitle=false'
+ '&pagenum=false'
+ '&gridlines=false'
+ '&fzr=FALSE'
+ '&gid='+sheetId;
var token = ScriptApp.getOAuthToken();
var docurl = UrlFetchApp.fetch(url, { headers: { 'Authorization': 'Bearer ' + token } });
var pdf = docurl.getAs('application/pdf');
var file = DriveApp.createFile(pdf);
var docId = sheet.getRange('F13').getValue();
var clientName = sheet.getRange('E9').getValue();
var docDate = sheet.getRange('F14').getValue();
var mois = docDate.getMonth()
docDate.setMonth((mois+1) % 12);
var docDateMMYY = docDate.getMonth()+"-"+docDate.getFullYear().toString().substr(-2);
var docName = "BL-"+docId+"-"+clientName+"-"+docDateMMYY ;
var folder = DriveApp.getFolderById("xxxxxxxxxxxxxxxxxxxx");
var finalFile = file.makeCopy(docName,folder);
file.setTrashed(true);
};
};
var cmdes = ss.getSheetByName('cmdes');
var raz = cmdes.getRange('S2:S501').setValue(false);
}
I think I had a good intuition and finally found the reason of my issue:
how-to-pause-app-scripts-until-spreadsheet-finishes-calculation
It looks like the loop runs faster than the spreadsheet calculation.
Sorry for inconvenience...

Microsoft Outlook Interop (extract attachments) very slow

I'm using Microsoft.Office.Interop.Outlook to extract e-mail attachments:
var MAPI = new Application().GetNamespace("MAPI");
var ExampleFolder = MAPI.GetDefaultFolder(OlDefaultFolders.olFolderSentMail)
foreach (dynamic i in ExampleFolder.Items)
if (i.Attachments.Count > 0)
; // DoSomething();
Unfortunately this is extremely slow.
Is there any faster way to check for attachments?
Is it possible to filter/sort e-mails by date: loop through the last n items only?
sure, you can sort the collection using Items.Sort.
You can also use Items.Find/FindNext or Items.Restrict to look for items with attachments only. The property you need is PR_HASATTACH (DASL name http://schemas.microsoft.com/mapi/proptag/0x0E1B000B)
#Kiquenet (I can't add a comment below yours), here is the code to get items with attachments from Items.Restrict:
//fanti's code
var MAPI = new Application().GetNamespace("MAPI");
var ExampleFolder = MAPI.GetDefaultFolder(OlDefaultFolders.olFolderSentMail)
Urn way (tested, ok -> source https://social.msdn.microsoft.com/Forums/windowsapps/en-US/b6fef244-756c-4ab0-a22b-78137cfb4349/datereceived-filter-nor-happeinig?forum=outlookdev):
var itemsWithAttachment = ExampleFolder.Items.Restrict("#SQL= urn:schemas:httpmail:hasattachment = True");
DASL way (tested, ko -> 'should work' source https://learn.microsoft.com/en-us/office/client-developer/outlook/pia/how-to-filter-and-efficiently-enumerate-items-in-a-folder):
const string PR_HAS_ATTACH = "https://schemas.microsoft.com/mapi/proptag/0x0E1B000B";
var itemsWithAttachment = ExampleFolder.Items.Restrict("#SQL=\"" + PR_HAS_ATTACH + "\" = 1");
To filter by a date, just add "AND"s or "OR"s like this (Urn way):
var itemsWithAttachmentAndDate = ExampleFolder.Items.Restrict("#SQL= urn:schemas:httpmail:hasattachment = True"
+ " AND urn:schemas:httpmail:datereceived <= '" + DateTime.Now.AddMonths(-3) + "'");
To loop through the last n items only:
int n = 3;
for (int i = itemsWithAttachmentAndDate.Count - 1; i > n; i--)
{
//current item: itemsWithAttachmentAndDate[i] //Beware: "dynamic" typed!
; //DoSomething();
}

Resources