spreadsheet in IE

14 views
Skip to first unread message

Mike B

unread,
Jul 8, 2010, 1:43:31 PM7/8/10
to Flotr Javascript Plotting Library
Hello. I'm using the spreadsheet feature for my charts. In Firefox the
'Download CSV' button results in a file save dialog as expected; in IE
the data is displayed in a new browser window. Is there a way to force
IE to present a file save dialog?

Thanks very much!

Fabien Ménager

unread,
Aug 19, 2010, 6:41:32 PM8/19/10
to Flotr Javascript Plotting Library
No there is no way without a server side script. If you really need
it, I could add an option for this.

Mike B

unread,
Aug 26, 2010, 12:12:18 PM8/26/10
to Flotr Javascript Plotting Library
Yes, we used a server-side script to get this done (steps are outlined
below). If anyone wants the code just reply to this thread and I'll
post it here.

The function we're calling from the chart object itself, in our case,
is passing two parameters: a reference to the table dom element
(this.spreadsheet.datagrid) and a dataname parameter. In our case the
dataname is being derived from the chart container id. Ultimately
we're using this as part of the exported file name, though that's not
needed to make this work. Also note that our function is designed to
accept either a table dom id or the element reference itself...in the
case of the charts we're using the latter.

The javascript is doing the following:

1) It initialized an empty array and traverses the tr tags of the
table. For each tr, it traverses all th and td tags and adds an
element to the array which itself is an array of the text in the th/td
tags. Therefore the array ends up with data something like this:

[
['col head 1', 'col head 1', 'col head 3'], [12, 55, 300], [5, 77,
230] ]

2) It JSON encodes that data into a string. We include the json2
javascript library for this, but this is where we discovered that
prototype breaks that when it comes to arrays. This will happen when
using flotr, so instead we use the prototype method of json encoding:

encdata = Object.toJSON(data);

...in place of the json2 JSON.stringify(data) method.

3) We add a form inside of a hidden span tag, whose action points to
the server side script url, to the dom containing a hidden input tag
with this data, submit the form, and delete all of that from the dom
when we're done.

4) The server side script json decodes that data (in the case of php
using json_decode) which gets an array or arrays. It prints the
appropriate headers for the desired content type and, most
importantly, the "Content-Disposition: attachment;
filename=<some_file_name>" header. It then traverses the array
printing out the data with the appropriate tab delimiters and newlines
at the end of each row.

Fabien Ménager

unread,
Aug 26, 2010, 1:33:36 PM8/26/10
to Flotr Javascript Plotting Library
Thank you for sharing this with us, I'd be very happy to see your
code!
I imagined it a bit easier. In fact, as we already have a formatted
CSV string built by Flotr, we could simply send it (with or without
the data URI header) to the server which would serve it with the
proper file name with the Content-Disposition header. And voilà ! No
json encode/decode.

Mike B

unread,
Aug 26, 2010, 2:20:30 PM8/26/10
to Flotr Javascript Plotting Library
Sure, basically we added a new function at the end of flotr.js called
exportTab and call that instead of downloadCSV. Here's that function
(btw, 'JQ' is how we call jQuery):

exportTab: function() {
var cdiv =
JQ(this.spreadsheet.datagrid).parents().filter('.flotrContainer');
var dataname = '';
if (cdiv.length) {
dataname = JQ(cdiv[0]).attr('id');
}
if (typeof(dataname) == 'undefined') {
dataname = '';
} else {
if (dataname.substring(0, 6) == 'flotr_') {
dataname = dataname.substring(6);
}
}
table_tabdelim_export(this.spreadsheet.datagrid, dataname);
}

===================================================

And here's the php:

<?php
require ('arxlibs/db_functions.php');

if ($_SERVER['REQUEST_METHOD'] != 'POST') exit();
if (!isset($_POST['data'])) exit();
$data = $_POST['data'];
if (isset($_POST['dataname'])) {
$dataname = $_POST['dataname'];
if (!empty($dataname)) $dataname .= '_';
} else {
$dataname = '';
}
$replacenl = isset($_POST['replacenl']) ? $_POST['replacenl'] : 0;
$filename = "myCompany_" . $dataname . date("Y-m-d-H.i.s") . ".dat";

$delim = "\t";

header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Disposition: attachment; filename=$filename");
header("Content-Transfer-Encoding: binary");

$data = json_decode($data);
foreach ($data as $row) {
if ($replacenl) {
$max = count($row);
for ($x = 0; $x < $max; $x++) {
$row[$x] = str_replace(array("\n", "\r"), ' ', $row[$x]);
}
}
print implode($delim, $row) . "\n";
}

?>


===================================================
Reply all
Reply to author
Forward
0 new messages