I'm using str_get_html http://simplehtmldom.sourceforge.net/ to export an HTML table to CSV. The user completes a form and the same table displays on screen. If they check a form box, I would like it to also generate a CSV file for download (in addition to displaying the table on screen).
Using ajax, I have the table being displayed in an empty div element.
<script type="text/javascript">
$(document).ready(function() {
var options = {target: '#output1'};
$('#completed').ajaxForm(options);});
</script>
It's almost working. The only problem is that it displays the CSV content in the div update, rather than generating a file for download. If I remove the on-screen display of the table and remove the ajax functionality, it generates the CSV file perfectly. Can someone help me with the code below so that it will generate a file for download?
include 'simple_html_dom.php';
$html = str_get_html($table);
header('Content-type: application/ms-excel');
header('Content-Disposition: attachment; filename=sample.csv');
$fp = fopen("php://output", "w");
foreach($html->find('tr') as $element)
{
$td = array();
foreach( $element->find('th') as $row)
{
$td [] = $row->plaintext;
}
fputcsv($fp, $td);
$td = array();
foreach( $element->find('td') as $row)
{
$td [] = $row->plaintext;
}
fputcsv($fp, $td);
}
fclose($fp);
Instead of using "php://output", you need to use a path/filename. Right now, you are telling php to write to the output buffer mechanism.
For example:
$fp = fopen("path/to/filename.csv", "w");
Related
I am making a script which gets a table from your mail and puts it into a CSV file.
This is the code I use to transfer my html table to CSV
$html = str_get_html($outputstr);
// For Excel
header('Content-type: application/ms-excel');
// Download File
header('Content-Disposition: attachment; filename=sample.csv');
$fp = fopen("php://output", "w");
// Take out empty lines
foreach($html->find('tr') as $element) {
$td = array();
foreach( $element->find('th') as $row) {
$td [] = $row->plaintext;
}
foreach( $element->find('td') as $row) {
$td [] = $row->plaintext;
}
fputcsv($fp, $td);
}
fclose($fp);
The only problem that I'm getting is that when I am opening the CSV file, some of the empty columns have a strange character:
I cannot read through with my PHP script to export it to a database
fgetcsv($handle, 1000, "\t");
How can I fix this problem?
Do I fix this by modifying the code on the part where I create the CSV file or where I read the CSV file when I'm transferring it to a MySQL database?
When I use an online html to CSV converter it works fine and I am not facing this issue then.
If there is any code needed then I'd love to share it.
Any help would be appreciated.
Have you tried setting your charset to UTF-8? Additionally, you're not setting this up as a CSV with your header, instead it is an Excel file.
header("content-type:application/csv;charset=UTF-8");
I don't have a lot of experience with using the fputcsv function.
I'm trying to make a function, by which an admin can download a file with all the user information.
The CSV should be generated in this way :
Serial Number Username Email etc etc
And then the records from a query.
I have this function which I'm using to generate the csv file :
function array_to_csv_download($array, $filename = "export.csv", $delimiter=";") {
// open raw memory as file so no temp files needed, you might run out of memory though
$f = fopen('php://memory', 'w');
// loop over the input array
foreach ($array as $line) {
// generate csv lines from the inner arrays
fputcsv($f, $line, $delimiter);
}
// rewrind the "file" with the csv lines
fseek($f, 0);
// tell the browser it's going to be a csv file
header('Content-Type: application/csv');
// tell the browser we want to save it instead of displaying it
header('Content-Disposition: attachement; filename="'.$filename.'";');
// make php send the generated csv lines to the browser
fpassthru($f);
}
And then I call the function:
<?php
include 'inc/inc.functions.php';
include 'dbconnector.php';
$query="SELECT * from users order by email LIMIT 0,30";
$result=mysql_query($query,$db) or die(mysql_error($db));
$array=mysql_fetch_array($result);
foreach($array as $arr)
{
array_to_csv_download($arr,"records.csv",":");
}
?>
The CSV generated displays: Warning, Invalid argument supplied for foreach.
What should I do to display in the way I require?
UPDATE
http://i.imgur.com/2xH0gT1.png
You're currently calling your function for a single row in the database, rather than for the entire result set. The following should use your function correctly:
$query = "SELECT * from users order by email LIMIT 0,30";
$result = mysql_query($query,$db) or die(mysql_error($db));
$array = array();
# Headers
$array[] = array("Serial Number","Username","Email","etc etc");
while($row = mysql_fetch_row($result)) {
$array[] = $row;
}
array_to_csv_download($array,"records.csv",":");
So I have an XML file that looks similar to this:
<container>
<example1>some text</example1>
<example2>some text</example2>
<example3>some text</example3>
<example4>some text</example4>
</container>
<container>
<example1>some text</example1>
<example2>some text</example2>
<example4>some text</example4>
</container>
Basically, if example3 doesn't contain any information, the XML author decided to leave it out completely. The trouble is, when I am using my script to convert to CSV, this particular XML file doesn't convert to CSV properly due to the text in the second example4 being displayed under the header of example3 in the CSV file.
This is the PHP script I have to normally works with other XML files.
$file='input.xml';
if (file_exists($file)) {
$xml = simplexml_load_file($file);
$f = fopen('output.csv', 'w');
// array to hold the field names
$headers = array();
// loop through the first set of fields to get names
foreach ($xml->container->children() as $field) {
// put the field name into array
$headers[] = $field->getName();
}
// print headers to CSV
fputcsv($f, $headers, ',', '"');
foreach ($xml->container as $information) {
fputcsv($f, get_object_vars($information), ',', '"');
}
fclose($f);
}
I can't figure out how to predefine the headers that I need and insert the correct information in the correct columns in the CSV.
Any pointers much appreciated.
thanks
mike
If your first entry always present all fields, then its enougth to iterate over the header fields for each line and look if the current line has all entrys.
foreach ($xml->container as $information) {
$vars = get_object_vars($information);
$line = array();
foreach($headers as $field) {
$line[] = isset($vars[$field]) ? $vars[$field] : '';
}
fputcsv($f, $line, ',', '"');
}
I need a way to make the fputscv function write data to the browser on-the-fly instead of creating a temporary file, saving data into that file and doing a echo file_get_contents().
Found this on the PHP docs website, first comment under the function reference:
function outputCSV($data) {
$outstream = fopen("php://output", 'w');
function __outputCSV(&$vals, $key, $filehandler) {
fputcsv($filehandler, $vals, ';', '"');
}
array_walk($data, '__outputCSV', $outstream);
fclose($outstream);
}
And a second option:
$csv = fopen('php://temp/maxmemory:'. (5*1024*1024), 'r+');
fputcsv($csv, array('blah','blah'));
rewind($csv);
// put it all in a variable
$output = stream_get_contents($csv);
Hope this helps!
BTW the PHP docs should always be your first stop when trying to figure things out. :-)
By a comment on the PHP site
<?php
$out = fopen('php://output', 'w');
fputcsv($out, array('this','is some', 'csv "stuff", you know.'));
fclose($out);
?>
As the original asker wanted to "write to the browser on the fly", maybe is worth noting (as was my case and noone mentioned it) that if you want to force a file name and a dialog asking to download a file in the browser, you must set the proper headers before outputting anything with fputcsv:
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=myFile.csv');
Producing a CSV is actually not all that difficult (parsing a CSV is a little bit more involved).
Sample code for writing a 2D Array as CSV:
$array = [
[1,2,3],
[4,5,6],
[7,8,9]
];
// If this CSV is a HTTP response you will need to set the right content type
header("Content-Type: text/csv");
// If you need to force download or set a filename (you can also do this with
// the download attribute in HTML5 instead)
header('Content-Disposition: attachment; filename="example.csv"')
// Column heading row, if required.
echo "Column heading 1,Column heading 2,Column heading 3\n";
foreach ($array as $row) {
$row = array_map(function($cell) {
// Cells containing a quote, a comma or a new line will need to be
// contained in double quotes.
if (preg_match('/["\n,]/', $cell)) {
// double quotes within cells need to be escaped.
return '"' . preg_replace('/"/', '""', $cell) . '"';
}
return $cell;
}, $row);
echo implode(',', $row) . "\n";
}
hey...i need to create a html+php+javascript interface
where i got three text area and i want::::
that if i'll enter some data into text area and pressing submit button,,then it'll enter that textarea's data into a csv file..
pls some one help....
<?php
$list = arrary();
//your array will have all the fields from the form, textfields and textareas
$fp = fopen('output.csv', 'w');
foreach ($list as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);
?>
$fp = fopen('file.csv', 'w');
fputcsv($fp, $_GET['TextArea']);
fclose($fp);
?>