Revision history for ShowCsv
Revision [19221]
Last edited on 2008-01-28 00:14:44 by NilsLindenberg [Modified links pointing to docs server]No Differences
Additions:
=====Showing the content of a csv-file=====
{{lastedit}}
if you save this as ##actions/showcsv.php##, you have the usage:
""{{showcsv file="uploads/file" seperator="," header="on" class="csvtableclass"}}""
- file is the name of the file (needs to be on the same server as the wikka?)
- seperator is the seperator for the entries
- if you set header="on", the first line will be used as the table-header.
- class is the css-class for the table. Standard is csvtable.
''use this only with trusted files or not at all till the possible security hole are closed (see below)!''
==To do==
- test if its possible to include files from other servers. Perhaps better to allow only files in the upload-path of wikka (possible security hole).
- add "csvtable" css
- documentation!!
==Notes==
- The file now requieres the HandleCsvData library.
- html tags in a csv-file are stripped (note that everything between <?php ?> will not be shown, too)
%%(php)
<?php
/**
* Prints a table based on a csv-textfile.
*
* With this action a csv file, which has to be on the same server as the wikki, is read and its content presented in a table.
*
* @author Nils Lindenberg (http://wikka.jsnx.com/NilsLindenberg)
*
* @param string file mandatory: the name of the file which should be shown
* @param char delimeter optional: the delimeter of the entries in the csv-file. Standard is ","
* @param ? header optional: if set to "on", the first entry will be shown strong. Standard is "off";
*
*/
require_once('library/handlecsvdata.php');
// ***Get the params ***
$header= 'off';
$separator = ",";
$filename = $vars['file'].".csv";
$tableclass = $vars['tableclass'];
if ($vars['separator']) $separator = $vars['separator'];
if ($vars['header']) $header = $vars['header'];
// *** Get the data and print the table ***
if (is_array($table = GetCsvData($filename, $separator, $tableclass))) PrintCsvTable($table, $header);
?>
%%
===Alternate Java based solution===
It is a great idea to be able to read csv files. I would like to propose an alternative re-using some Java code I built years ago.
The concept is just a bit different as the input file has to be in this form:
<<"Title for column 1","Title for column 2",...
"Row 1 data 1","Row 1 data 2",...
"Row 2 data 1","Row 2 data 2",...
<<::c::
This allows to have some data with the separator inside the data not being split and considered as two data.
%%(java)
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.io.*;
import java.util.*;
import netscape.javascript.JSObject;
import java.net.URL;
public class CsvReader extends Applet {
private JSObject win;
private int number_hidden;
private int number_input;
private String[] args =new String[258];
private Hashtable hiddens= new Hashtable();
private Hashtable inputs= new Hashtable();
private String[] result = new String[1];
/* this method parses one data line from the input file and generates HTML code. Some elements may have to be hidden or have to be inputable depending on the parameters used*/
private String parseLign(String value)
{
String table;
table="<tr>";
int compt=0;
int i;
String temp="";
while((i=value.indexOf(",\""))!=-1)
{
temp = value.substring(1,i-1);
value = value.substring(i+1);
if (hiddens.containsKey(args[compt]))
{
compt++;
continue;
}
if (inputs.containsKey(args[compt])) table+="<td> <INPUT type=text size=8 value="+temp+" ></td>";
else table+="<td>"+temp+"</td>";
compt++;
}
if (!hiddens.containsKey(args[compt]))
{
if (inputs.containsKey(args[compt])) table+="<td> <INPUT type=text size=8 value="+value.substring(1,value.length()-1)+" ></td>";
else table+="<td>"+value.substring(1,value.length()-1)+"</td>";
}
table+="</tr>";
return table;
}
/* this method parses the 1st data line (considered as titles) as generates a string table that contains all titles for all columns */
private void parseArgs(String str) {
int compt =0;
int i;
String temp;
while((i=str.indexOf(",\""))!=-1)
{
temp = str.substring(1,i-1);
str= str.substring(i+1);
args[compt] = temp;
compt++;
}
args[compt]=str.substring(1,str.length()-1);
}
/* this method uses the table of the column titles (built here above) and the input parameters (elements to be hidden, elements to be input) stocked as hashtable to generate the HTML code for the titles*/
private String parseTitle() {
String str= "<TABLE border=\"2\" bordercolor=\"#0033CC\" bgcolor=\"#999999\"><TR>";
int i =0;
while (args[i]!=null)
{
if (hiddens.containsKey(args[i])) {i++;continue;}
str += "<td>"+args[i]+"</td>";
i++;
}
str+= "</tr>";
return str;
}
//Applet initialisation
public void init() {
try
{
win = JSObject.getWindow(this);
number_hidden=new Integer(getParameter("number_hidden")).intValue();
number_input=new Integer(getParameter("number_input")).intValue();
for (int i=0;i<number_hidden;i++)
{
hiddens.put(getParameter("hidden"+i),"hidden");
}
for (int i=0;i<number_input;i++)
{
inputs.put(getParameter("input"+i),"input");
}
URL url = new URL(getCodeBase(),getParameter("datafile"));
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
parseArgs(br.readLine());
String temp;
result[0]= parseTitle();
while ((temp=br.readLine())!=null)
{
result[0] += parseLign(temp);
}
result[0] += "</table>";
win.call("display",result);
}
catch (Exception e)
{showStatus("Error during initialisation");}
}
}
%%
Finally your HTML code should look like this:
%%(html)
<script LANGUAGE="JavaScript">
function display(str){document.body.insertAdjacentHTML('beforeEnd',str);}
</SCRIPT>
</head>
<body>
<APPLET
CODE = "CsvReader.class"
WIDTH = 1
HEIGHT = 1
HSPACE = 0
VSPACE = 0
ALIGN = center
MAYSCRIPT
>
<PARAM name=datafile value=data/MyFile.csv>
<PARAM name=number_hidden value=2>
<PARAM name=hidden0 value=TitleX>
<PARAM name=hidden1 value=TitleY>
<PARAM name=number_input value=3>
<PARAM name=input0 value=TitleA>
<PARAM name=input1 value=TitleB>
<PARAM name=input2 value=TitleC>
</APPLET>
%%
As you can see, there is one line of javascript called by the java code (win.call("display",result);) to display the html code in your page.
===How to use it?===
The input file has to be formatted as explained above (in fact a csv file with all data inside double quotes and the first row being the column titles).
The applet needs a few parameters:
- the input file (datafile): here it is MyFile.csv
- you may hide some columns, to do this you have to:
- provide the number of hidden columns through the parameter number_hidden
- list then all titles (from the actual csv file first column contents) through the parameters hidden0, hidden1...
- you may have some columns as input fields, to do this you have to:
- provide the number of input columns through the parameter number_input
- list then all titles (from the actual csv file first column contents) through the parameters input0, input1...
===To Do===
Test it intensively,
Decide what to do when input have been made in the input fields (replace the input file?),
Get the comments of a java expert: looking at the user nicknames in this wiki we should find some ;-)
~&Although a Java-based solution may sound nice, there are actually some big disadvantages to this:
~~-People who choose Wikka as a solution because they already know PHP or would be prepared to learn some, may be disappointed to also have to learn Java (which is, frankly, not as easy to learn as PHP); and one language is quite enough to deal with for a beginner. And apart from learning the language, not everyone has a Java compiler to build an applet either: A PHP solution could at least be "easily" adapted by anyone who needs a tweak.
~~-The solution requires an applet to be embedded rather than an action code - which is not something even experienced Wiki page authors are likely to be be familiar with (at the very least there should be an action "wrapper" which outputs the ##applet## HTML element (or better: an ##object## since ##applet## is deprecated)).
~~-This solution requires the site visitor to have Java (JRE at least) installed **and** enabled **and** of the correct version (I just went through downloading and installing a new JRE just to be able to see a FreeMind mindmap example...); this would exclude many visitors fom seeing the data.
~~-The solution requires JavaScript which many site vistotors have diabled (or don't have available at all); relying on JavaScript for functionality is therefore not a good idea (although it's fine to use as //enhancement// of functionality that is provided without JavaScript. Again, this would exclude many visitors from seeing thr data.
~&All that said, it may not be so hard to translate the code from Java to PHP, and would welcome a proposal so we can compare the two alternatives in the same language. --JavaWoman (who is not a Java expert ;-))
----
CategoryUserContributions
{{lastedit}}
if you save this as ##actions/showcsv.php##, you have the usage:
""{{showcsv file="uploads/file" seperator="," header="on" class="csvtableclass"}}""
- file is the name of the file (needs to be on the same server as the wikka?)
- seperator is the seperator for the entries
- if you set header="on", the first line will be used as the table-header.
- class is the css-class for the table. Standard is csvtable.
''use this only with trusted files or not at all till the possible security hole are closed (see below)!''
==To do==
- test if its possible to include files from other servers. Perhaps better to allow only files in the upload-path of wikka (possible security hole).
- add "csvtable" css
- documentation!!
==Notes==
- The file now requieres the HandleCsvData library.
- html tags in a csv-file are stripped (note that everything between <?php ?> will not be shown, too)
%%(php)
<?php
/**
* Prints a table based on a csv-textfile.
*
* With this action a csv file, which has to be on the same server as the wikki, is read and its content presented in a table.
*
* @author Nils Lindenberg (http://wikka.jsnx.com/NilsLindenberg)
*
* @param string file mandatory: the name of the file which should be shown
* @param char delimeter optional: the delimeter of the entries in the csv-file. Standard is ","
* @param ? header optional: if set to "on", the first entry will be shown strong. Standard is "off";
*
*/
require_once('library/handlecsvdata.php');
// ***Get the params ***
$header= 'off';
$separator = ",";
$filename = $vars['file'].".csv";
$tableclass = $vars['tableclass'];
if ($vars['separator']) $separator = $vars['separator'];
if ($vars['header']) $header = $vars['header'];
// *** Get the data and print the table ***
if (is_array($table = GetCsvData($filename, $separator, $tableclass))) PrintCsvTable($table, $header);
?>
%%
===Alternate Java based solution===
It is a great idea to be able to read csv files. I would like to propose an alternative re-using some Java code I built years ago.
The concept is just a bit different as the input file has to be in this form:
<<"Title for column 1","Title for column 2",...
"Row 1 data 1","Row 1 data 2",...
"Row 2 data 1","Row 2 data 2",...
<<::c::
This allows to have some data with the separator inside the data not being split and considered as two data.
%%(java)
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.io.*;
import java.util.*;
import netscape.javascript.JSObject;
import java.net.URL;
public class CsvReader extends Applet {
private JSObject win;
private int number_hidden;
private int number_input;
private String[] args =new String[258];
private Hashtable hiddens= new Hashtable();
private Hashtable inputs= new Hashtable();
private String[] result = new String[1];
/* this method parses one data line from the input file and generates HTML code. Some elements may have to be hidden or have to be inputable depending on the parameters used*/
private String parseLign(String value)
{
String table;
table="<tr>";
int compt=0;
int i;
String temp="";
while((i=value.indexOf(",\""))!=-1)
{
temp = value.substring(1,i-1);
value = value.substring(i+1);
if (hiddens.containsKey(args[compt]))
{
compt++;
continue;
}
if (inputs.containsKey(args[compt])) table+="<td> <INPUT type=text size=8 value="+temp+" ></td>";
else table+="<td>"+temp+"</td>";
compt++;
}
if (!hiddens.containsKey(args[compt]))
{
if (inputs.containsKey(args[compt])) table+="<td> <INPUT type=text size=8 value="+value.substring(1,value.length()-1)+" ></td>";
else table+="<td>"+value.substring(1,value.length()-1)+"</td>";
}
table+="</tr>";
return table;
}
/* this method parses the 1st data line (considered as titles) as generates a string table that contains all titles for all columns */
private void parseArgs(String str) {
int compt =0;
int i;
String temp;
while((i=str.indexOf(",\""))!=-1)
{
temp = str.substring(1,i-1);
str= str.substring(i+1);
args[compt] = temp;
compt++;
}
args[compt]=str.substring(1,str.length()-1);
}
/* this method uses the table of the column titles (built here above) and the input parameters (elements to be hidden, elements to be input) stocked as hashtable to generate the HTML code for the titles*/
private String parseTitle() {
String str= "<TABLE border=\"2\" bordercolor=\"#0033CC\" bgcolor=\"#999999\"><TR>";
int i =0;
while (args[i]!=null)
{
if (hiddens.containsKey(args[i])) {i++;continue;}
str += "<td>"+args[i]+"</td>";
i++;
}
str+= "</tr>";
return str;
}
//Applet initialisation
public void init() {
try
{
win = JSObject.getWindow(this);
number_hidden=new Integer(getParameter("number_hidden")).intValue();
number_input=new Integer(getParameter("number_input")).intValue();
for (int i=0;i<number_hidden;i++)
{
hiddens.put(getParameter("hidden"+i),"hidden");
}
for (int i=0;i<number_input;i++)
{
inputs.put(getParameter("input"+i),"input");
}
URL url = new URL(getCodeBase(),getParameter("datafile"));
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
parseArgs(br.readLine());
String temp;
result[0]= parseTitle();
while ((temp=br.readLine())!=null)
{
result[0] += parseLign(temp);
}
result[0] += "</table>";
win.call("display",result);
}
catch (Exception e)
{showStatus("Error during initialisation");}
}
}
%%
Finally your HTML code should look like this:
%%(html)
<script LANGUAGE="JavaScript">
function display(str){document.body.insertAdjacentHTML('beforeEnd',str);}
</SCRIPT>
</head>
<body>
<APPLET
CODE = "CsvReader.class"
WIDTH = 1
HEIGHT = 1
HSPACE = 0
VSPACE = 0
ALIGN = center
MAYSCRIPT
>
<PARAM name=datafile value=data/MyFile.csv>
<PARAM name=number_hidden value=2>
<PARAM name=hidden0 value=TitleX>
<PARAM name=hidden1 value=TitleY>
<PARAM name=number_input value=3>
<PARAM name=input0 value=TitleA>
<PARAM name=input1 value=TitleB>
<PARAM name=input2 value=TitleC>
</APPLET>
%%
As you can see, there is one line of javascript called by the java code (win.call("display",result);) to display the html code in your page.
===How to use it?===
The input file has to be formatted as explained above (in fact a csv file with all data inside double quotes and the first row being the column titles).
The applet needs a few parameters:
- the input file (datafile): here it is MyFile.csv
- you may hide some columns, to do this you have to:
- provide the number of hidden columns through the parameter number_hidden
- list then all titles (from the actual csv file first column contents) through the parameters hidden0, hidden1...
- you may have some columns as input fields, to do this you have to:
- provide the number of input columns through the parameter number_input
- list then all titles (from the actual csv file first column contents) through the parameters input0, input1...
===To Do===
Test it intensively,
Decide what to do when input have been made in the input fields (replace the input file?),
Get the comments of a java expert: looking at the user nicknames in this wiki we should find some ;-)
~&Although a Java-based solution may sound nice, there are actually some big disadvantages to this:
~~-People who choose Wikka as a solution because they already know PHP or would be prepared to learn some, may be disappointed to also have to learn Java (which is, frankly, not as easy to learn as PHP); and one language is quite enough to deal with for a beginner. And apart from learning the language, not everyone has a Java compiler to build an applet either: A PHP solution could at least be "easily" adapted by anyone who needs a tweak.
~~-The solution requires an applet to be embedded rather than an action code - which is not something even experienced Wiki page authors are likely to be be familiar with (at the very least there should be an action "wrapper" which outputs the ##applet## HTML element (or better: an ##object## since ##applet## is deprecated)).
~~-This solution requires the site visitor to have Java (JRE at least) installed **and** enabled **and** of the correct version (I just went through downloading and installing a new JRE just to be able to see a FreeMind mindmap example...); this would exclude many visitors fom seeing the data.
~~-The solution requires JavaScript which many site vistotors have diabled (or don't have available at all); relying on JavaScript for functionality is therefore not a good idea (although it's fine to use as //enhancement// of functionality that is provided without JavaScript. Again, this would exclude many visitors from seeing thr data.
~&All that said, it may not be so hard to translate the code from Java to PHP, and would welcome a proposal so we can compare the two alternatives in the same language. --JavaWoman (who is not a Java expert ;-))
----
CategoryUserContributions
Deletions:
{{lastedit}}
if you save this as ##actions/showcsv.php##, you have the usage:
""{{showcsv file="uploads/file" seperator="," header="on" class="csvtableclass"}}""
- file is the name of the file (needs to be on the same server as the wikka?)
- seperator is the seperator for the entries
- if you set header="on", the first line will be used as the table-header.
- class is the css-class for the table. Standard is csvtable.
''use this only with trusted files or not at all till the possible security hole are closed (see below)!''
==To do==
- test if its possible to include files from other servers. Perhaps better to allow only files in the upload-path of wikka (possible security hole).
- add "csvtable" css
- documentation!!
==Notes==
- The file now requieres the HandleCsvData library.
- html tags in a csv-file are stripped (note that everything between <?php ?> will not be shown, too)
%%(php)
<?php
/**
* Prints a table based on a csv-textfile.
*
* With this action a csv file, which has to be on the same server as the wikki, is read and its content presented in a table.
*
* @author Nils Lindenberg (http://wikka.jsnx.com/NilsLindenberg)
*
* @param string file mandatory: the name of the file which should be shown
* @param char delimeter optional: the delimeter of the entries in the csv-file. Standard is ","
* @param ? header optional: if set to "on", the first entry will be shown strong. Standard is "off";
*
*/
require_once('library/handlecsvdata.php');
// ***Get the params ***
$header= 'off';
$separator = ",";
$filename = $vars['file'].".csv";
$tableclass = $vars['tableclass'];
if ($vars['separator']) $separator = $vars['separator'];
if ($vars['header']) $header = $vars['header'];
// *** Get the data and print the table ***
if (is_array($table = GetCsvData($filename, $separator, $tableclass))) PrintCsvTable($table, $header);
?>
%%
===Alternate Java based solution===
It is a great idea to be able to read csv files. I would like to propose an alternative re-using some Java code I built years ago.
The concept is just a bit different as the input file has to be in this form:
<<"Title for column 1","Title for column 2",...
"Row 1 data 1","Row 1 data 2",...
"Row 2 data 1","Row 2 data 2",...
<<::c::
This allows to have some data with the separator inside the data not being split and considered as two data.
%%(java)
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.io.*;
import java.util.*;
import netscape.javascript.JSObject;
import java.net.URL;
public class CsvReader extends Applet {
private JSObject win;
private int number_hidden;
private int number_input;
private String[] args =new String[258];
private Hashtable hiddens= new Hashtable();
private Hashtable inputs= new Hashtable();
private String[] result = new String[1];
/* this method parses one data line from the input file and generates HTML code. Some elements may have to be hidden or have to be inputable depending on the parameters used*/
private String parseLign(String value)
{
String table;
table="<tr>";
int compt=0;
int i;
String temp="";
while((i=value.indexOf(",\""))!=-1)
{
temp = value.substring(1,i-1);
value = value.substring(i 1);
if (hiddens.containsKey(args[compt]))
{
compt ;
continue;
}
if (inputs.containsKey(args[compt])) table ="<td> <INPUT type=text size=8 value=" temp " ></td>";
else table ="<td>" temp "</td>";
compt ;
}
if (!hiddens.containsKey(args[compt]))
{
if (inputs.containsKey(args[compt])) table ="<td> <INPUT type=text size=8 value=" value.substring(1,value.length()-1) " ></td>";
else table ="<td>" value.substring(1,value.length()-1) "</td>";
}
table ="</tr>";
return table;
}
/* this method parses the 1st data line (considered as titles) as generates a string table that contains all titles for all columns */
private void parseArgs(String str) {
int compt =0;
int i;
String temp;
while((i=str.indexOf(",\""))!=-1)
{
temp = str.substring(1,i-1);
str= str.substring(i 1);
args[compt] = temp;
compt ;
}
args[compt]=str.substring(1,str.length()-1);
}
/* this method uses the table of the column titles (built here above) and the input parameters (elements to be hidden, elements to be input) stocked as hashtable to generate the HTML code for the titles*/
private String parseTitle() {
String str= "<TABLE border=\"2\" bordercolor=\"#0033CC\" bgcolor=\"#999999\"><TR>";
int i =0;
while (args[i]!=null)
{
if (hiddens.containsKey(args[i])) {i ;continue;}
str = "<td>" args[i] "</td>";
i ;
}
str = "</tr>";
return str;
}
//Applet initialisation
public void init() {
try
{
win = JSObject.getWindow(this);
number_hidden=new Integer(getParameter("number_hidden")).intValue();
number_input=new Integer(getParameter("number_input")).intValue();
for (int i=0;i<number_hidden;i )
{
hiddens.put(getParameter("hidden" i),"hidden");
}
for (int i=0;i<number_input;i )
{
inputs.put(getParameter("input" i),"input");
}
URL url = new URL(getCodeBase(),getParameter("datafile"));
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
parseArgs(br.readLine());
String temp;
result[0]= parseTitle();
while ((temp=br.readLine())!=null)
{
result[0] = parseLign(temp);
}
result[0] = "</table>";
win.call("display",result);
}
catch (Exception e)
{showStatus("Error during initialisation");}
}
}
%%
Finally your HTML code should look like this:
%%(html)
<script LANGUAGE="JavaScript">
function display(str){document.body.insertAdjacentHTML('beforeEnd',str);}
</SCRIPT>
</head>
<body>
<APPLET
CODE = "CsvReader.class"
WIDTH = 1
HEIGHT = 1
HSPACE = 0
VSPACE = 0
ALIGN = center
MAYSCRIPT
>
<PARAM name=datafile value=data/MyFile.csv>
<PARAM name=number_hidden value=2>
<PARAM name=hidden0 value=TitleX>
<PARAM name=hidden1 value=TitleY>
<PARAM name=number_input value=3>
<PARAM name=input0 value=TitleA>
<PARAM name=input1 value=TitleB>
<PARAM name=input2 value=TitleC>
</APPLET>
%%
As you can see, there is one line of javascript called by the java code (win.call("display",result);) to display the html code in your page.
===How to use it?===
The input file has to be formatted as explained above (in fact a csv file with all data inside double quotes and the first row being the column titles).
The applet needs a few parameters:
- the input file (datafile): here it is MyFile.csv
- you may hide some columns, to do this you have to:
- provide the number of hidden columns through the parameter number_hidden
- list then all titles (from the actual csv file first column contents) through the parameters hidden0, hidden1...
- you may have some columns as input fields, to do this you have to:
- provide the number of input columns through the parameter number_input
- list then all titles (from the actual csv file first column contents) through the parameters input0, input1...
===To Do===
Test it intensively,
Decide what to do when input have been made in the input fields (replace the input file?),
Get the comments of a java expert: looking at the user nicknames in this wiki we should find some ;-)
~
Additions:
=====Showing the content of a csv-file=====
{{lastedit}}
if you save this as ##actions/showcsv.php##, you have the usage:
""{{showcsv file="uploads/file" seperator="," header="on" class="csvtableclass"}}""
- file is the name of the file (needs to be on the same server as the wikka?)
- seperator is the seperator for the entries
- if you set header="on", the first line will be used as the table-header.
- class is the css-class for the table. Standard is csvtable.
''use this only with trusted files or not at all till the possible security hole are closed (see below)!''
==To do==
- test if its possible to include files from other servers. Perhaps better to allow only files in the upload-path of wikka (possible security hole).
- add "csvtable" css
- documentation!!
==Notes==
- The file now requieres the HandleCsvData library.
- html tags in a csv-file are stripped (note that everything between <?php ?> will not be shown, too)
%%(php)
<?php
/**
* Prints a table based on a csv-textfile.
*
* With this action a csv file, which has to be on the same server as the wikki, is read and its content presented in a table.
*
* @author Nils Lindenberg (http://wikka.jsnx.com/NilsLindenberg)
*
* @param string file mandatory: the name of the file which should be shown
* @param char delimeter optional: the delimeter of the entries in the csv-file. Standard is ","
* @param ? header optional: if set to "on", the first entry will be shown strong. Standard is "off";
*
*/
require_once('library/handlecsvdata.php');
// ***Get the params ***
$header= 'off';
$separator = ",";
$filename = $vars['file'].".csv";
$tableclass = $vars['tableclass'];
if ($vars['separator']) $separator = $vars['separator'];
if ($vars['header']) $header = $vars['header'];
// *** Get the data and print the table ***
if (is_array($table = GetCsvData($filename, $separator, $tableclass))) PrintCsvTable($table, $header);
?>
%%
===Alternate Java based solution===
It is a great idea to be able to read csv files. I would like to propose an alternative re-using some Java code I built years ago.
The concept is just a bit different as the input file has to be in this form:
<<"Title for column 1","Title for column 2",...
"Row 1 data 1","Row 1 data 2",...
"Row 2 data 1","Row 2 data 2",...
<<::c::
This allows to have some data with the separator inside the data not being split and considered as two data.
%%(java)
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.io.*;
import java.util.*;
import netscape.javascript.JSObject;
import java.net.URL;
public class CsvReader extends Applet {
private JSObject win;
private int number_hidden;
private int number_input;
private String[] args =new String[258];
private Hashtable hiddens= new Hashtable();
private Hashtable inputs= new Hashtable();
private String[] result = new String[1];
/* this method parses one data line from the input file and generates HTML code. Some elements may have to be hidden or have to be inputable depending on the parameters used*/
private String parseLign(String value)
{
String table;
table="<tr>";
int compt=0;
int i;
String temp="";
while((i=value.indexOf(",\""))!=-1)
{
temp = value.substring(1,i-1);
value = value.substring(i 1);
if (hiddens.containsKey(args[compt]))
{
compt ;
continue;
}
if (inputs.containsKey(args[compt])) table ="<td> <INPUT type=text size=8 value=" temp " ></td>";
else table ="<td>" temp "</td>";
compt ;
}
if (!hiddens.containsKey(args[compt]))
{
if (inputs.containsKey(args[compt])) table ="<td> <INPUT type=text size=8 value=" value.substring(1,value.length()-1) " ></td>";
else table ="<td>" value.substring(1,value.length()-1) "</td>";
}
table ="</tr>";
return table;
}
/* this method parses the 1st data line (considered as titles) as generates a string table that contains all titles for all columns */
private void parseArgs(String str) {
int compt =0;
int i;
String temp;
while((i=str.indexOf(",\""))!=-1)
{
temp = str.substring(1,i-1);
str= str.substring(i 1);
args[compt] = temp;
compt ;
}
args[compt]=str.substring(1,str.length()-1);
}
/* this method uses the table of the column titles (built here above) and the input parameters (elements to be hidden, elements to be input) stocked as hashtable to generate the HTML code for the titles*/
private String parseTitle() {
String str= "<TABLE border=\"2\" bordercolor=\"#0033CC\" bgcolor=\"#999999\"><TR>";
int i =0;
while (args[i]!=null)
{
if (hiddens.containsKey(args[i])) {i ;continue;}
str = "<td>" args[i] "</td>";
i ;
}
str = "</tr>";
return str;
}
//Applet initialisation
public void init() {
try
{
win = JSObject.getWindow(this);
number_hidden=new Integer(getParameter("number_hidden")).intValue();
number_input=new Integer(getParameter("number_input")).intValue();
for (int i=0;i<number_hidden;i )
{
hiddens.put(getParameter("hidden" i),"hidden");
}
for (int i=0;i<number_input;i )
{
inputs.put(getParameter("input" i),"input");
}
URL url = new URL(getCodeBase(),getParameter("datafile"));
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
parseArgs(br.readLine());
String temp;
result[0]= parseTitle();
while ((temp=br.readLine())!=null)
{
result[0] = parseLign(temp);
}
result[0] = "</table>";
win.call("display",result);
}
catch (Exception e)
{showStatus("Error during initialisation");}
}
}
%%
Finally your HTML code should look like this:
%%(html)
<script LANGUAGE="JavaScript">
function display(str){document.body.insertAdjacentHTML('beforeEnd',str);}
</SCRIPT>
</head>
<body>
<APPLET
CODE = "CsvReader.class"
WIDTH = 1
HEIGHT = 1
HSPACE = 0
VSPACE = 0
ALIGN = center
MAYSCRIPT
>
<PARAM name=datafile value=data/MyFile.csv>
<PARAM name=number_hidden value=2>
<PARAM name=hidden0 value=TitleX>
<PARAM name=hidden1 value=TitleY>
<PARAM name=number_input value=3>
<PARAM name=input0 value=TitleA>
<PARAM name=input1 value=TitleB>
<PARAM name=input2 value=TitleC>
</APPLET>
%%
As you can see, there is one line of javascript called by the java code (win.call("display",result);) to display the html code in your page.
===How to use it?===
The input file has to be formatted as explained above (in fact a csv file with all data inside double quotes and the first row being the column titles).
The applet needs a few parameters:
- the input file (datafile): here it is MyFile.csv
- you may hide some columns, to do this you have to:
- provide the number of hidden columns through the parameter number_hidden
- list then all titles (from the actual csv file first column contents) through the parameters hidden0, hidden1...
- you may have some columns as input fields, to do this you have to:
- provide the number of input columns through the parameter number_input
- list then all titles (from the actual csv file first column contents) through the parameters input0, input1...
===To Do===
Test it intensively,
Decide what to do when input have been made in the input fields (replace the input file?),
Get the comments of a java expert: looking at the user nicknames in this wiki we should find some ;-)
~
{{lastedit}}
if you save this as ##actions/showcsv.php##, you have the usage:
""{{showcsv file="uploads/file" seperator="," header="on" class="csvtableclass"}}""
- file is the name of the file (needs to be on the same server as the wikka?)
- seperator is the seperator for the entries
- if you set header="on", the first line will be used as the table-header.
- class is the css-class for the table. Standard is csvtable.
''use this only with trusted files or not at all till the possible security hole are closed (see below)!''
==To do==
- test if its possible to include files from other servers. Perhaps better to allow only files in the upload-path of wikka (possible security hole).
- add "csvtable" css
- documentation!!
==Notes==
- The file now requieres the HandleCsvData library.
- html tags in a csv-file are stripped (note that everything between <?php ?> will not be shown, too)
%%(php)
<?php
/**
* Prints a table based on a csv-textfile.
*
* With this action a csv file, which has to be on the same server as the wikki, is read and its content presented in a table.
*
* @author Nils Lindenberg (http://wikka.jsnx.com/NilsLindenberg)
*
* @param string file mandatory: the name of the file which should be shown
* @param char delimeter optional: the delimeter of the entries in the csv-file. Standard is ","
* @param ? header optional: if set to "on", the first entry will be shown strong. Standard is "off";
*
*/
require_once('library/handlecsvdata.php');
// ***Get the params ***
$header= 'off';
$separator = ",";
$filename = $vars['file'].".csv";
$tableclass = $vars['tableclass'];
if ($vars['separator']) $separator = $vars['separator'];
if ($vars['header']) $header = $vars['header'];
// *** Get the data and print the table ***
if (is_array($table = GetCsvData($filename, $separator, $tableclass))) PrintCsvTable($table, $header);
?>
%%
===Alternate Java based solution===
It is a great idea to be able to read csv files. I would like to propose an alternative re-using some Java code I built years ago.
The concept is just a bit different as the input file has to be in this form:
<<"Title for column 1","Title for column 2",...
"Row 1 data 1","Row 1 data 2",...
"Row 2 data 1","Row 2 data 2",...
<<::c::
This allows to have some data with the separator inside the data not being split and considered as two data.
%%(java)
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.io.*;
import java.util.*;
import netscape.javascript.JSObject;
import java.net.URL;
public class CsvReader extends Applet {
private JSObject win;
private int number_hidden;
private int number_input;
private String[] args =new String[258];
private Hashtable hiddens= new Hashtable();
private Hashtable inputs= new Hashtable();
private String[] result = new String[1];
/* this method parses one data line from the input file and generates HTML code. Some elements may have to be hidden or have to be inputable depending on the parameters used*/
private String parseLign(String value)
{
String table;
table="<tr>";
int compt=0;
int i;
String temp="";
while((i=value.indexOf(",\""))!=-1)
{
temp = value.substring(1,i-1);
value = value.substring(i 1);
if (hiddens.containsKey(args[compt]))
{
compt ;
continue;
}
if (inputs.containsKey(args[compt])) table ="<td> <INPUT type=text size=8 value=" temp " ></td>";
else table ="<td>" temp "</td>";
compt ;
}
if (!hiddens.containsKey(args[compt]))
{
if (inputs.containsKey(args[compt])) table ="<td> <INPUT type=text size=8 value=" value.substring(1,value.length()-1) " ></td>";
else table ="<td>" value.substring(1,value.length()-1) "</td>";
}
table ="</tr>";
return table;
}
/* this method parses the 1st data line (considered as titles) as generates a string table that contains all titles for all columns */
private void parseArgs(String str) {
int compt =0;
int i;
String temp;
while((i=str.indexOf(",\""))!=-1)
{
temp = str.substring(1,i-1);
str= str.substring(i 1);
args[compt] = temp;
compt ;
}
args[compt]=str.substring(1,str.length()-1);
}
/* this method uses the table of the column titles (built here above) and the input parameters (elements to be hidden, elements to be input) stocked as hashtable to generate the HTML code for the titles*/
private String parseTitle() {
String str= "<TABLE border=\"2\" bordercolor=\"#0033CC\" bgcolor=\"#999999\"><TR>";
int i =0;
while (args[i]!=null)
{
if (hiddens.containsKey(args[i])) {i ;continue;}
str = "<td>" args[i] "</td>";
i ;
}
str = "</tr>";
return str;
}
//Applet initialisation
public void init() {
try
{
win = JSObject.getWindow(this);
number_hidden=new Integer(getParameter("number_hidden")).intValue();
number_input=new Integer(getParameter("number_input")).intValue();
for (int i=0;i<number_hidden;i )
{
hiddens.put(getParameter("hidden" i),"hidden");
}
for (int i=0;i<number_input;i )
{
inputs.put(getParameter("input" i),"input");
}
URL url = new URL(getCodeBase(),getParameter("datafile"));
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
parseArgs(br.readLine());
String temp;
result[0]= parseTitle();
while ((temp=br.readLine())!=null)
{
result[0] = parseLign(temp);
}
result[0] = "</table>";
win.call("display",result);
}
catch (Exception e)
{showStatus("Error during initialisation");}
}
}
%%
Finally your HTML code should look like this:
%%(html)
<script LANGUAGE="JavaScript">
function display(str){document.body.insertAdjacentHTML('beforeEnd',str);}
</SCRIPT>
</head>
<body>
<APPLET
CODE = "CsvReader.class"
WIDTH = 1
HEIGHT = 1
HSPACE = 0
VSPACE = 0
ALIGN = center
MAYSCRIPT
>
<PARAM name=datafile value=data/MyFile.csv>
<PARAM name=number_hidden value=2>
<PARAM name=hidden0 value=TitleX>
<PARAM name=hidden1 value=TitleY>
<PARAM name=number_input value=3>
<PARAM name=input0 value=TitleA>
<PARAM name=input1 value=TitleB>
<PARAM name=input2 value=TitleC>
</APPLET>
%%
As you can see, there is one line of javascript called by the java code (win.call("display",result);) to display the html code in your page.
===How to use it?===
The input file has to be formatted as explained above (in fact a csv file with all data inside double quotes and the first row being the column titles).
The applet needs a few parameters:
- the input file (datafile): here it is MyFile.csv
- you may hide some columns, to do this you have to:
- provide the number of hidden columns through the parameter number_hidden
- list then all titles (from the actual csv file first column contents) through the parameters hidden0, hidden1...
- you may have some columns as input fields, to do this you have to:
- provide the number of input columns through the parameter number_input
- list then all titles (from the actual csv file first column contents) through the parameters input0, input1...
===To Do===
Test it intensively,
Decide what to do when input have been made in the input fields (replace the input file?),
Get the comments of a java expert: looking at the user nicknames in this wiki we should find some ;-)
~
Deletions:
{{lastedit}}
if you save this as ##actions/showcsv.php##, you have the usage:
""{{showcsv file="uploads/file" seperator="," header="on" class="csvtableclass"}}""
- file is the name of the file (needs to be on the same server as the wikka?)
- seperator is the seperator for the entries
- if you set header="on", the first line will be used as the table-header.
- class is the css-class for the table. Standard is csvtable.
''use this only with trusted files or not at all till the possible security hole are closed (see below)!''
==To do==
- test if its possible to include files from other servers. Perhaps better to allow only files in the upload-path of wikka (possible security hole).
- add "csvtable" css
- documentation!!
==Notes==
- The file now requieres the HandleCsvData library.
- html tags in a csv-file are stripped (note that everything between <?php ?> will not be shown, too)
%%(php)
<?php
/**
* Prints a table based on a csv-textfile.
*
* With this action a csv file, which has to be on the same server as the wikki, is read and its content presented in a table.
*
* @author Nils Lindenberg (http://wikka.jsnx.com/NilsLindenberg)
*
* @param string file mandatory: the name of the file which should be shown
* @param char delimeter optional: the delimeter of the entries in the csv-file. Standard is ","
* @param ? header optional: if set to "on", the first entry will be shown strong. Standard is "off";
*
*/
require_once('library/handlecsvdata.php');
// ***Get the params ***
$header= 'off';
$separator = ",";
$filename = $vars['file'].".csv";
$tableclass = $vars['tableclass'];
if ($vars['separator']) $separator = $vars['separator'];
if ($vars['header']) $header = $vars['header'];
// *** Get the data and print the table ***
if (is_array($table = GetCsvData($filename, $separator, $tableclass))) PrintCsvTable($table, $header);
?>
%%
===Alternate Java based solution===
It is a great idea to be able to read csv files. I would like to propose an alternative re-using some Java code I built years ago.
The concept is just a bit different as the input file has to be in this form:
<<"Title for column 1","Title for column 2",...
"Row 1 data 1","Row 1 data 2",...
"Row 2 data 1","Row 2 data 2",...
<<::c::
This allows to have some data with the separator inside the data not being split and considered as two data.
%%(java)
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.io.*;
import java.util.*;
import netscape.javascript.JSObject;
import java.net.URL;
public class CsvReader extends Applet {
private JSObject win;
private int number_hidden;
private int number_input;
private String[] args =new String[258];
private Hashtable hiddens= new Hashtable();
private Hashtable inputs= new Hashtable();
private String[] result = new String[1];
/* this method parses one data line from the input file and generates HTML code. Some elements may have to be hidden or have to be inputable depending on the parameters used*/
private String parseLign(String value)
{
String table;
table="<tr>";
int compt=0;
int i;
String temp="";
while((i=value.indexOf(",\""))!=-1)
{
temp = value.substring(1,i-1);
value = value.substring(i+1);
if (hiddens.containsKey(args[compt]))
{
compt++;
continue;
}
if (inputs.containsKey(args[compt])) table+="<td> <INPUT type=text size=8 value="+temp+" ></td>";
else table+="<td>"+temp+"</td>";
compt++;
}
if (!hiddens.containsKey(args[compt]))
{
if (inputs.containsKey(args[compt])) table+="<td> <INPUT type=text size=8 value="+value.substring(1,value.length()-1)+" ></td>";
else table+="<td>"+value.substring(1,value.length()-1)+"</td>";
}
table+="</tr>";
return table;
}
/* this method parses the 1st data line (considered as titles) as generates a string table that contains all titles for all columns */
private void parseArgs(String str) {
int compt =0;
int i;
String temp;
while((i=str.indexOf(",\""))!=-1)
{
temp = str.substring(1,i-1);
str= str.substring(i+1);
args[compt] = temp;
compt++;
}
args[compt]=str.substring(1,str.length()-1);
}
/* this method uses the table of the column titles (built here above) and the input parameters (elements to be hidden, elements to be input) stocked as hashtable to generate the HTML code for the titles*/
private String parseTitle() {
String str= "<TABLE border=\"2\" bordercolor=\"#0033CC\" bgcolor=\"#999999\"><TR>";
int i =0;
while (args[i]!=null)
{
if (hiddens.containsKey(args[i])) {i++;continue;}
str += "<td>"+args[i]+"</td>";
i++;
}
str+= "</tr>";
return str;
}
//Applet initialisation
public void init() {
try
{
win = JSObject.getWindow(this);
number_hidden=new Integer(getParameter("number_hidden")).intValue();
number_input=new Integer(getParameter("number_input")).intValue();
for (int i=0;i<number_hidden;i++)
{
hiddens.put(getParameter("hidden"+i),"hidden");
}
for (int i=0;i<number_input;i++)
{
inputs.put(getParameter("input"+i),"input");
}
URL url = new URL(getCodeBase(),getParameter("datafile"));
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
parseArgs(br.readLine());
String temp;
result[0]= parseTitle();
while ((temp=br.readLine())!=null)
{
result[0] += parseLign(temp);
}
result[0] += "</table>";
win.call("display",result);
}
catch (Exception e)
{showStatus("Error during initialisation");}
}
}
%%
Finally your HTML code should look like this:
%%(html)
<script LANGUAGE="JavaScript">
function display(str){document.body.insertAdjacentHTML('beforeEnd',str);}
</SCRIPT>
</head>
<body>
<APPLET
CODE = "CsvReader.class"
WIDTH = 1
HEIGHT = 1
HSPACE = 0
VSPACE = 0
ALIGN = center
MAYSCRIPT
>
<PARAM name=datafile value=data/MyFile.csv>
<PARAM name=number_hidden value=2>
<PARAM name=hidden0 value=TitleX>
<PARAM name=hidden1 value=TitleY>
<PARAM name=number_input value=3>
<PARAM name=input0 value=TitleA>
<PARAM name=input1 value=TitleB>
<PARAM name=input2 value=TitleC>
</APPLET>
%%
As you can see, there is one line of javascript called by the java code (win.call("display",result);) to display the html code in your page.
===How to use it?===
The input file has to be formatted as explained above (in fact a csv file with all data inside double quotes and the first row being the column titles).
The applet needs a few parameters:
- the input file (datafile): here it is MyFile.csv
- you may hide some columns, to do this you have to:
- provide the number of hidden columns through the parameter number_hidden
- list then all titles (from the actual csv file first column contents) through the parameters hidden0, hidden1...
- you may have some columns as input fields, to do this you have to:
- provide the number of input columns through the parameter number_input
- list then all titles (from the actual csv file first column contents) through the parameters input0, input1...
===To Do===
Test it intensively,
Decide what to do when input have been made in the input fields (replace the input file?),
Get the comments of a java expert: looking at the user nicknames in this wiki we should find some ;-)
~&Although a Java-based solution may sound nice, there are actually some big disadvantages to this:
~~-People who choose Wikka as a solution because they already know PHP or would be prepared to learn some, may be disappointed to also have to learn Java (which is, frankly, not as easy to learn as PHP); and one language is quite enough to deal with for a beginner. And apart from learning the language, not everyone has a Java compiler to build an applet either: A PHP solution could at least be "easily" adapted by anyone who needs a tweak.
~~-The solution requires an applet to be embedded rather than an action code - which is not something even experienced Wiki page authors are likely to be be familiar with (at the very least there should be an action "wrapper" which outputs the ##applet## HTML element (or better: an ##object## since ##applet## is deprecated)).
~~-This solution requires the site visitor to have Java (JRE at least) installed **and** enabled **and** of the correct version (I just went through downloading and installing a new JRE just to be able to see a FreeMind mindmap example...); this would exclude many visitors fom seeing the data.
~~-The solution requires JavaScript which many site vistotors have diabled (or don't have available at all); relying on JavaScript for functionality is therefore not a good idea (although it's fine to use as //enhancement// of functionality that is provided without JavaScript. Again, this would exclude many visitors from seeing thr data.
~&All that said, it may not be so hard to translate the code from Java to PHP, and would welcome a proposal so we can compare the two alternatives in the same language. --JavaWoman (who is not a Java expert ;-))
----
CategoryUserContributions
Revision [5186]
Edited on 2005-01-25 16:36:58 by NilsLindenberg [documentation + lowercase for some html-tags]Additions:
*
* @param string file mandatory: the name of the file which should be shown
* @param char delimeter optional: the delimeter of the entries in the csv-file. Standard is ","
* @param ? header optional: if set to "on", the first entry will be shown strong. Standard is "off";
// ***Get the params ***
// *** Get the data and print the table ***
table="<tr>";
if (inputs.containsKey(args[compt])) table+="<td> <INPUT type=text size=8 value="+temp+" ></td>";
else table+="<td>"+temp+"</td>";
if (inputs.containsKey(args[compt])) table+="<td> <INPUT type=text size=8 value="+value.substring(1,value.length()-1)+" ></td>";
else table+="<td>"+value.substring(1,value.length()-1)+"</td>";
table+="</tr>";
str += "<td>"+args[i]+"</td>";
str+= "</tr>";
result[0] += "</table>";
<script LANGUAGE="JavaScript">
</head>
<body>
* @param string file mandatory: the name of the file which should be shown
* @param char delimeter optional: the delimeter of the entries in the csv-file. Standard is ","
* @param ? header optional: if set to "on", the first entry will be shown strong. Standard is "off";
// ***Get the params ***
// *** Get the data and print the table ***
table="<tr>";
if (inputs.containsKey(args[compt])) table+="<td> <INPUT type=text size=8 value="+temp+" ></td>";
else table+="<td>"+temp+"</td>";
if (inputs.containsKey(args[compt])) table+="<td> <INPUT type=text size=8 value="+value.substring(1,value.length()-1)+" ></td>";
else table+="<td>"+value.substring(1,value.length()-1)+"</td>";
table+="</tr>";
str += "<td>"+args[i]+"</td>";
str+= "</tr>";
result[0] += "</table>";
<script LANGUAGE="JavaScript">
</head>
<body>
Deletions:
* file string mandatory the name of the file which should be shown
* delimeter char optional the delimeter of the entries in the csv-file. Standard is ","
* header ? optional if set to "on", the first entry will be shown strong. Standard is "off";
//parameters
table="<TR>";
if (inputs.containsKey(args[compt])) table+="<TD> <INPUT type=text size=8 value="+temp+" ></TD>";
else table+="<TD>"+temp+"</TD>";
if (inputs.containsKey(args[compt])) table+="<TD> <INPUT type=text size=8 value="+value.substring(1,value.length()-1)+" ></TD>";
else table+="<TD>"+value.substring(1,value.length()-1)+"</TD>";
table+="</TR>";
str += "<TD>"+args[i]+"</TD>";
str+= "</TR>";
result[0] += "</TABLE>";
<SCRIPT LANGUAGE="JavaScript">
</HEAD>
<BODY>
Additions:
""{{showcsv file="uploads/file" seperator="," header="on" class="csvtableclass"}}""
- class is the css-class for the table. Standard is csvtable.
''use this only with trusted files or not at all till the possible security hole are closed (see below)!''
- add "csvtable" css
- documentation!!
==Notes==
- The file now requieres the HandleCsvData library.
- html tags in a csv-file are stripped (note that everything between <?php ?> will not be shown, too)
* file string mandatory the name of the file which should be shown
* delimeter char optional the delimeter of the entries in the csv-file. Standard is ","
* header ? optional if set to "on", the first entry will be shown strong. Standard is "off";
require_once('library/handlecsvdata.php');
$header= 'off';
$separator = ",";
$filename = $vars['file'].".csv";
$tableclass = $vars['tableclass'];
if ($vars['separator']) $separator = $vars['separator'];
if (is_array($table = GetCsvData($filename, $separator, $tableclass))) PrintCsvTable($table, $header);
- class is the css-class for the table. Standard is csvtable.
''use this only with trusted files or not at all till the possible security hole are closed (see below)!''
- add "csvtable" css
- documentation!!
==Notes==
- The file now requieres the HandleCsvData library.
- html tags in a csv-file are stripped (note that everything between <?php ?> will not be shown, too)
* file string mandatory the name of the file which should be shown
* delimeter char optional the delimeter of the entries in the csv-file. Standard is ","
* header ? optional if set to "on", the first entry will be shown strong. Standard is "off";
require_once('library/handlecsvdata.php');
$header= 'off';
$separator = ",";
$filename = $vars['file'].".csv";
$tableclass = $vars['tableclass'];
if ($vars['separator']) $separator = $vars['separator'];
if (is_array($table = GetCsvData($filename, $separator, $tableclass))) PrintCsvTable($table, $header);
Deletions:
''use this only with trusted files or not at all till the two possible security holes are closed (see below)!''
- ++allow only *.csv files++
- big security hole: cause the content of the file is renderd with the html-code of the page, you can add html-code (and surely php/javascript too). Question for a solution in ProgrammingHelp
- look for the difference of excel *.csv and normal csv
- possibility of sorting the entries?
* @author Stefan Lindenberg (http://wikka.jsnx.com/NilsLindenberg)
* file string mandatory the name of the file which should be shown (without the .csv ending)
* delimeter char optional the delimeter of the entries in the csv-file. standard is ","
* header string optional if set to "on", the first entry will be used as header. Standard is "off".
$file = $vars['file'].".csv";
if ($vars['seperator']) $seperator = $vars['seperator'];
else $seperator = ",";
else $header = "off";
if (file_exists($file))
$id = fopen($file, "r");
while ($data = fgetcsv($id, filesize($file), $seperator))
{
$line[] = $data; //put each line into its own entry in the $table array
}
fclose($id);
//print the table
echo "<table border=1>\n";
//first entry handeld seperate, possible header
echo "<tr>\n";
for ($i = 0; $i<count($line); $i++)
{
if ($header == 'on') echo "<th>";
else echo "<td>";
echo $line[0][$i];
if ($header == 'on') echo "</th>\n";
else echo "</td>\n";
}
echo "</tr>\n";
for($j=1;$j<count($line);$j++)
{
for ($k=0; $k<count($line[$j]);$k++)
echo "<td>";
echo $line[$k][$j];
echo "</td>\n";
echo "</tr>\n";
}
echo "</table>\n";
else print("File .".$file.". not found.");
Additions:
~&All that said, it may not be so hard to translate the code from Java to PHP, and would welcome a proposal so we can compare the two alternatives in the same language. --JavaWoman (who is not a Java expert ;-))
----
CategoryUserContributions
----
CategoryUserContributions
Deletions:
Revision [4649]
Edited on 2005-01-15 16:48:43 by NilsLindenberg [code changes + security holes added]Additions:
""{{showcsv file="uploads/file" seperator="," header="on"}}""
- if you set header="on", the first line will be used as the table-header.
''use this only with trusted files or not at all till the two possible security holes are closed (see below)!''
==To do==
- ++allow only *.csv files++
- test if its possible to include files from other servers. Perhaps better to allow only files in the upload-path of wikka (possible security hole).
- big security hole: cause the content of the file is renderd with the html-code of the page, you can add html-code (and surely php/javascript too). Question for a solution in ProgrammingHelp
- look for the difference of excel *.csv and normal csv
- possibility of sorting the entries?
* file string mandatory the name of the file which should be shown (without the .csv ending)
* header string optional if set to "on", the first entry will be used as header. Standard is "off".
$file = $vars['file'].".csv";
if (file_exists($file))
$id = fopen($file, "r");
while ($data = fgetcsv($id, filesize($file), $seperator))
$line[] = $data; //put each line into its own entry in the $table array
for ($i = 0; $i<count($line); $i++)
echo $line[0][$i];
for($j=1;$j<count($line);$j++)
for ($k=0; $k<count($line[$j]);$k++)
echo $line[$k][$j];
else print("File .".$file.". not found.");
- if you set header="on", the first line will be used as the table-header.
''use this only with trusted files or not at all till the two possible security holes are closed (see below)!''
==To do==
- ++allow only *.csv files++
- test if its possible to include files from other servers. Perhaps better to allow only files in the upload-path of wikka (possible security hole).
- big security hole: cause the content of the file is renderd with the html-code of the page, you can add html-code (and surely php/javascript too). Question for a solution in ProgrammingHelp
- look for the difference of excel *.csv and normal csv
- possibility of sorting the entries?
* file string mandatory the name of the file which should be shown (without the .csv ending)
* header string optional if set to "on", the first entry will be used as header. Standard is "off".
$file = $vars['file'].".csv";
if (file_exists($file))
$id = fopen($file, "r");
while ($data = fgetcsv($id, filesize($file), $seperator))
$line[] = $data; //put each line into its own entry in the $table array
for ($i = 0; $i<count($line); $i++)
echo $line[0][$i];
for($j=1;$j<count($line);$j++)
for ($k=0; $k<count($line[$j]);$k++)
echo $line[$k][$j];
else print("File .".$file.". not found.");
Deletions:
- if you set header="on", the first entry in the file will be printed **strong**
===Bugs===
At the moment, there is a bug if you use a , as seperator or in your file. the explode of the entries on a line won't work. I have no clue why. You can see it [[http://niehle.info/SandBox here]].
* file string mandatory the name of the file which should be shown
* header string optional if set to "on", the first entry will be used as header. Standard is "off";
$filename = $vars['file'];
if (file_exists($filename))
$id = fopen($filename, "r");
while ($data = fgetcsv($id, filesize($filename)))
$table[] = $data; //put each line into its own entry in the $table array
$entry = explode($seperator, $table[0][0]);
for ($j = 0; $j < count($entry); $j++)
echo $entry[$j];
for($i=1;$i<count($table);$i++)
$entry = explode($seperator, $table[$i][0]);
for ($j=0; $j < count($entry); $j++)
echo $entry[$j];
else print("File not found.");
Additions:
Get the comments of a java expert: looking at the user nicknames in this wiki we should find some ;-)
~&Although a Java-based solution may sound nice, there are actually some big disadvantages to this:
~~-People who choose Wikka as a solution because they already know PHP or would be prepared to learn some, may be disappointed to also have to learn Java (which is, frankly, not as easy to learn as PHP); and one language is quite enough to deal with for a beginner. And apart from learning the language, not everyone has a Java compiler to build an applet either: A PHP solution could at least be "easily" adapted by anyone who needs a tweak.
~~-The solution requires an applet to be embedded rather than an action code - which is not something even experienced Wiki page authors are likely to be be familiar with (at the very least there should be an action "wrapper" which outputs the ##applet## HTML element (or better: an ##object## since ##applet## is deprecated)).
~~-This solution requires the site visitor to have Java (JRE at least) installed **and** enabled **and** of the correct version (I just went through downloading and installing a new JRE just to be able to see a FreeMind mindmap example...); this would exclude many visitors fom seeing the data.
~~-The solution requires JavaScript which many site vistotors have diabled (or don't have available at all); relying on JavaScript for functionality is therefore not a good idea (although it's fine to use as //enhancement// of functionality that is provided without JavaScript. Again, this would exclude many visitors from seeing thr data.
~&All that said, it may not be so hard to translate the code from Java to PHP, and would welcome a proposal so we can compare the two alternatives in the same language. --JavaWoman (who is not a Java expert ;-))
~&Although a Java-based solution may sound nice, there are actually some big disadvantages to this:
~~-People who choose Wikka as a solution because they already know PHP or would be prepared to learn some, may be disappointed to also have to learn Java (which is, frankly, not as easy to learn as PHP); and one language is quite enough to deal with for a beginner. And apart from learning the language, not everyone has a Java compiler to build an applet either: A PHP solution could at least be "easily" adapted by anyone who needs a tweak.
~~-The solution requires an applet to be embedded rather than an action code - which is not something even experienced Wiki page authors are likely to be be familiar with (at the very least there should be an action "wrapper" which outputs the ##applet## HTML element (or better: an ##object## since ##applet## is deprecated)).
~~-This solution requires the site visitor to have Java (JRE at least) installed **and** enabled **and** of the correct version (I just went through downloading and installing a new JRE just to be able to see a FreeMind mindmap example...); this would exclude many visitors fom seeing the data.
~~-The solution requires JavaScript which many site vistotors have diabled (or don't have available at all); relying on JavaScript for functionality is therefore not a good idea (although it's fine to use as //enhancement// of functionality that is provided without JavaScript. Again, this would exclude many visitors from seeing thr data.
~&All that said, it may not be so hard to translate the code from Java to PHP, and would welcome a proposal so we can compare the two alternatives in the same language. --JavaWoman (who is not a Java expert ;-))
Deletions:
Revision [4594]
Edited on 2005-01-13 14:51:41 by ChristianBarthelemy [What about a java alternative?]Additions:
%%
===Alternate Java based solution===
It is a great idea to be able to read csv files. I would like to propose an alternative re-using some Java code I built years ago.
The concept is just a bit different as the input file has to be in this form:
<<"Title for column 1","Title for column 2",...
"Row 1 data 1","Row 1 data 2",...
"Row 2 data 1","Row 2 data 2",...
<<::c::
This allows to have some data with the separator inside the data not being split and considered as two data.
%%(java)
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.io.*;
import java.util.*;
import netscape.javascript.JSObject;
import java.net.URL;
public class CsvReader extends Applet {
private JSObject win;
private int number_hidden;
private int number_input;
private String[] args =new String[258];
private Hashtable hiddens= new Hashtable();
private Hashtable inputs= new Hashtable();
private String[] result = new String[1];
/* this method parses one data line from the input file and generates HTML code. Some elements may have to be hidden or have to be inputable depending on the parameters used*/
private String parseLign(String value)
String table;
table="<TR>";
int compt=0;
int i;
String temp="";
while((i=value.indexOf(",\""))!=-1)
{
temp = value.substring(1,i-1);
value = value.substring(i+1);
if (hiddens.containsKey(args[compt]))
{
compt++;
continue;
}
if (inputs.containsKey(args[compt])) table+="<TD> <INPUT type=text size=8 value="+temp+" ></TD>";
else table+="<TD>"+temp+"</TD>";
compt++;
}
if (!hiddens.containsKey(args[compt]))
if (inputs.containsKey(args[compt])) table+="<TD> <INPUT type=text size=8 value="+value.substring(1,value.length()-1)+" ></TD>";
else table+="<TD>"+value.substring(1,value.length()-1)+"</TD>";
table+="</TR>";
return table;
}
/* this method parses the 1st data line (considered as titles) as generates a string table that contains all titles for all columns */
private void parseArgs(String str) {
int compt =0;
int i;
String temp;
while((i=str.indexOf(",\""))!=-1)
{
temp = str.substring(1,i-1);
str= str.substring(i+1);
args[compt] = temp;
compt++;
}
args[compt]=str.substring(1,str.length()-1);
}
/* this method uses the table of the column titles (built here above) and the input parameters (elements to be hidden, elements to be input) stocked as hashtable to generate the HTML code for the titles*/
private String parseTitle() {
String str= "<TABLE border=\"2\" bordercolor=\"#0033CC\" bgcolor=\"#999999\"><TR>";
int i =0;
while (args[i]!=null)
{
if (hiddens.containsKey(args[i])) {i++;continue;}
str += "<TD>"+args[i]+"</TD>";
i++;
}
str+= "</TR>";
return str;
}
//Applet initialisation
public void init() {
try
{
win = JSObject.getWindow(this);
number_hidden=new Integer(getParameter("number_hidden")).intValue();
number_input=new Integer(getParameter("number_input")).intValue();
for (int i=0;i<number_hidden;i++)
{
hiddens.put(getParameter("hidden"+i),"hidden");
}
for (int i=0;i<number_input;i++)
{
inputs.put(getParameter("input"+i),"input");
}
URL url = new URL(getCodeBase(),getParameter("datafile"));
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
parseArgs(br.readLine());
String temp;
result[0]= parseTitle();
while ((temp=br.readLine())!=null)
{
result[0] += parseLign(temp);
}
result[0] += "</TABLE>";
win.call("display",result);
}
catch (Exception e)
{showStatus("Error during initialisation");}
}
%%
Finally your HTML code should look like this:
%%(html)
<SCRIPT LANGUAGE="JavaScript">
function display(str){document.body.insertAdjacentHTML('beforeEnd',str);}
</SCRIPT>
</HEAD>
<BODY>
<APPLET
CODE = "CsvReader.class"
WIDTH = 1
HEIGHT = 1
HSPACE = 0
VSPACE = 0
ALIGN = center
MAYSCRIPT
>
<PARAM name=datafile value=data/MyFile.csv>
<PARAM name=number_hidden value=2>
<PARAM name=hidden0 value=TitleX>
<PARAM name=hidden1 value=TitleY>
<PARAM name=number_input value=3>
<PARAM name=input0 value=TitleA>
<PARAM name=input1 value=TitleB>
<PARAM name=input2 value=TitleC>
</APPLET>
%%
As you can see, there is one line of javascript called by the java code (win.call("display",result);) to display the html code in your page.
===How to use it?===
The input file has to be formatted as explained above (in fact a csv file with all data inside double quotes and the first row being the column titles).
The applet needs a few parameters:
- the input file (datafile): here it is MyFile.csv
- you may hide some columns, to do this you have to:
- provide the number of hidden columns through the parameter number_hidden
- list then all titles (from the actual csv file first column contents) through the parameters hidden0, hidden1...
- you may have some columns as input fields, to do this you have to:
- provide the number of input columns through the parameter number_input
- list then all titles (from the actual csv file first column contents) through the parameters input0, input1...
===To Do===
Test it intensively,
Decide what to do when input have been made in the input fields (replace the input file?),
Get the comments of a java expert: looking at the user nicknames in this wiki we should find some ;-)
===Alternate Java based solution===
It is a great idea to be able to read csv files. I would like to propose an alternative re-using some Java code I built years ago.
The concept is just a bit different as the input file has to be in this form:
<<"Title for column 1","Title for column 2",...
"Row 1 data 1","Row 1 data 2",...
"Row 2 data 1","Row 2 data 2",...
<<::c::
This allows to have some data with the separator inside the data not being split and considered as two data.
%%(java)
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.io.*;
import java.util.*;
import netscape.javascript.JSObject;
import java.net.URL;
public class CsvReader extends Applet {
private JSObject win;
private int number_hidden;
private int number_input;
private String[] args =new String[258];
private Hashtable hiddens= new Hashtable();
private Hashtable inputs= new Hashtable();
private String[] result = new String[1];
/* this method parses one data line from the input file and generates HTML code. Some elements may have to be hidden or have to be inputable depending on the parameters used*/
private String parseLign(String value)
String table;
table="<TR>";
int compt=0;
int i;
String temp="";
while((i=value.indexOf(",\""))!=-1)
{
temp = value.substring(1,i-1);
value = value.substring(i+1);
if (hiddens.containsKey(args[compt]))
{
compt++;
continue;
}
if (inputs.containsKey(args[compt])) table+="<TD> <INPUT type=text size=8 value="+temp+" ></TD>";
else table+="<TD>"+temp+"</TD>";
compt++;
}
if (!hiddens.containsKey(args[compt]))
if (inputs.containsKey(args[compt])) table+="<TD> <INPUT type=text size=8 value="+value.substring(1,value.length()-1)+" ></TD>";
else table+="<TD>"+value.substring(1,value.length()-1)+"</TD>";
table+="</TR>";
return table;
}
/* this method parses the 1st data line (considered as titles) as generates a string table that contains all titles for all columns */
private void parseArgs(String str) {
int compt =0;
int i;
String temp;
while((i=str.indexOf(",\""))!=-1)
{
temp = str.substring(1,i-1);
str= str.substring(i+1);
args[compt] = temp;
compt++;
}
args[compt]=str.substring(1,str.length()-1);
}
/* this method uses the table of the column titles (built here above) and the input parameters (elements to be hidden, elements to be input) stocked as hashtable to generate the HTML code for the titles*/
private String parseTitle() {
String str= "<TABLE border=\"2\" bordercolor=\"#0033CC\" bgcolor=\"#999999\"><TR>";
int i =0;
while (args[i]!=null)
{
if (hiddens.containsKey(args[i])) {i++;continue;}
str += "<TD>"+args[i]+"</TD>";
i++;
}
str+= "</TR>";
return str;
}
//Applet initialisation
public void init() {
try
{
win = JSObject.getWindow(this);
number_hidden=new Integer(getParameter("number_hidden")).intValue();
number_input=new Integer(getParameter("number_input")).intValue();
for (int i=0;i<number_hidden;i++)
{
hiddens.put(getParameter("hidden"+i),"hidden");
}
for (int i=0;i<number_input;i++)
{
inputs.put(getParameter("input"+i),"input");
}
URL url = new URL(getCodeBase(),getParameter("datafile"));
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
parseArgs(br.readLine());
String temp;
result[0]= parseTitle();
while ((temp=br.readLine())!=null)
{
result[0] += parseLign(temp);
}
result[0] += "</TABLE>";
win.call("display",result);
}
catch (Exception e)
{showStatus("Error during initialisation");}
}
%%
Finally your HTML code should look like this:
%%(html)
<SCRIPT LANGUAGE="JavaScript">
function display(str){document.body.insertAdjacentHTML('beforeEnd',str);}
</SCRIPT>
</HEAD>
<BODY>
<APPLET
CODE = "CsvReader.class"
WIDTH = 1
HEIGHT = 1
HSPACE = 0
VSPACE = 0
ALIGN = center
MAYSCRIPT
>
<PARAM name=datafile value=data/MyFile.csv>
<PARAM name=number_hidden value=2>
<PARAM name=hidden0 value=TitleX>
<PARAM name=hidden1 value=TitleY>
<PARAM name=number_input value=3>
<PARAM name=input0 value=TitleA>
<PARAM name=input1 value=TitleB>
<PARAM name=input2 value=TitleC>
</APPLET>
%%
As you can see, there is one line of javascript called by the java code (win.call("display",result);) to display the html code in your page.
===How to use it?===
The input file has to be formatted as explained above (in fact a csv file with all data inside double quotes and the first row being the column titles).
The applet needs a few parameters:
- the input file (datafile): here it is MyFile.csv
- you may hide some columns, to do this you have to:
- provide the number of hidden columns through the parameter number_hidden
- list then all titles (from the actual csv file first column contents) through the parameters hidden0, hidden1...
- you may have some columns as input fields, to do this you have to:
- provide the number of input columns through the parameter number_input
- list then all titles (from the actual csv file first column contents) through the parameters input0, input1...
===To Do===
Test it intensively,
Decide what to do when input have been made in the input fields (replace the input file?),
Get the comments of a java expert: looking at the user nicknames in this wiki we should find some ;-)
Deletions:
Additions:
* file string mandatory the name of the file which should be shown
* delimeter char optional the delimeter of the entries in the csv-file. standard is ","
* header string optional if set to "on", the first entry will be used as header. Standard is "off";
if ($header == 'on') echo "<th>";
else echo "<td>";
if ($header == 'on') echo "</th>\n";
else echo "</td>\n";
* delimeter char optional the delimeter of the entries in the csv-file. standard is ","
* header string optional if set to "on", the first entry will be used as header. Standard is "off";
if ($header == 'on') echo "<th>";
else echo "<td>";
if ($header == 'on') echo "</th>\n";
else echo "</td>\n";
Deletions:
* delimeter char optional the delimeter of the entries in the csv-file. standard is ","
* header type? optional if set to "on", the first entry will be shown strong. Standard is "off";
echo "<td>";
if ($header == 'on') echo "<strong>";
if ($header == 'on') echo "</strong>";
echo "</td>\n";
Additions:
""{{showcsv file="uploads/file.csv" seperator="," header="on"}}""
Deletions:
Additions:
===Bugs===
At the moment, there is a bug if you use a , as seperator or in your file. the explode of the entries on a line won't work. I have no clue why. You can see it [[http://niehle.info/SandBox here]].
* @author Stefan Lindenberg (http://wikka.jsnx.com/NilsLindenberg)
At the moment, there is a bug if you use a , as seperator or in your file. the explode of the entries on a line won't work. I have no clue why. You can see it [[http://niehle.info/SandBox here]].
* @author Stefan Lindenberg (http://wikka.jsnx.com/NilsLindenberg)
Deletions:
Additions:
{{lastedit}}
""{{showcsv file="uploads/file.csv" seperator=","' header="on"}}""
- file is the name of the file (needs to be on the same server as the wikka?)
- seperator is the seperator for the entries
- if you set header="on", the first entry in the file will be printed **strong**
At the moment, there is a bug if you use a , as seperator or in your file. the explode of the entries on a line won#t work. I have no clue why. You can see it [[http://niehle.info/SandBox here]].
* header type? optional if set to "on", the first entry will be shown strong. Standard is "off";
//parameters
if ($vars['seperator']) $seperator = $vars['seperator'];
else $seperator = ",";
if ($vars['header']) $header = $vars['header'];
else $header = "off";
//first entry handeld seperate, possible header
$entry = explode($seperator, $table[0][0]);
echo "<tr>\n";
for ($j = 0; $j < count($entry); $j++)
echo "<td>";
if ($header == 'on') echo "<strong>";
echo $entry[$j];
if ($header == 'on') echo "</strong>";
echo "</td>\n";
echo "</tr>\n";
for($i=1;$i<count($table);$i++)
$entry = explode($seperator, $table[$i][0]);
echo $entry[$j];
""{{showcsv file="uploads/file.csv" seperator=","' header="on"}}""
- file is the name of the file (needs to be on the same server as the wikka?)
- seperator is the seperator for the entries
- if you set header="on", the first entry in the file will be printed **strong**
At the moment, there is a bug if you use a , as seperator or in your file. the explode of the entries on a line won#t work. I have no clue why. You can see it [[http://niehle.info/SandBox here]].
* header type? optional if set to "on", the first entry will be shown strong. Standard is "off";
//parameters
if ($vars['seperator']) $seperator = $vars['seperator'];
else $seperator = ",";
if ($vars['header']) $header = $vars['header'];
else $header = "off";
//first entry handeld seperate, possible header
$entry = explode($seperator, $table[0][0]);
echo "<tr>\n";
for ($j = 0; $j < count($entry); $j++)
echo "<td>";
if ($header == 'on') echo "<strong>";
echo $entry[$j];
if ($header == 'on') echo "</strong>";
echo "</td>\n";
echo "</tr>\n";
for($i=1;$i<count($table);$i++)
$entry = explode($seperator, $table[$i][0]);
echo $entry[$j];
Deletions:
file is the name of the file - needs to be on the same server as the wikka(?)
delimeter is the seperator for the entries
ToDo:
-document
//get the params
if ($vars['delimeter']) $delimeter = $vars['delimeter'];
else $delimeter = ',';
for($i=0;$i<count($table);$i++)
$entry = explode($delimeter, $table[$i][0]);
echo "<tr>\n";
echo $entry[$j]."<br />";