Working on PHP converting to excel, but having problems in the excel file where it doesn't add each row in its own cell. Here is how it looks: https://www.dropbox.com/s/64lz7lqy8z7x72j/export.csv
It writes it on the first cell and it looks like it has written to all of the cell.
And here is the PHP code:
<?php
$conn = mysql_connect('localhost', 'root', '') or die(mysql_error());
mysql_select_db('chart', $conn) or die(mysql_error($conn));
$result = mysql_query('SELECT * FROM chartgoogle', $conn) or die(mysql_error($conn));
header('Content-Type: text/csv'); // tell the browser to treat file as CSV
header('Content-Disposition: attachment;filename=export.csv'); // tell browser to download a file in user's system with name export.csv
$row = mysql_fetch_assoc($result); // Get the column names
if ($row) {
outputcsv(array_keys($row)); // It wil pass column names to outputcsv function
}
while ($row) {
outputcsv($row); // loop is used to fetch all the rows from table and pass them to outputcsv func
$row = mysql_fetch_assoc($result);
}
function outputcsv($fields) {
$separator = '';
foreach ($fields as $field) {
echo $separator . $field;
$separator = ','; // Separate values with a comma
}
echo "\r\n"; //Give a carriage return and new line space after each record
}
?>
Try this :
function outputcsv($fields) {
$csv = '';
foreach ($fields as $field) {
$csv .= '"' . $field . '",';
}
$csv .= "\r\n"; //Give a carriage return and new line space after each record
echo $csv;
}
Take a look at the double quotes placed before and after the field. CSV files usually use double quotes as closures. They call it text qualifier.
Related
I am exporting to CSV from my php reporting website. I have reports that are more than 80k rows. When I export one of them the whole data set does not get exported. I have tried several times with a report that is 88k+ rows and it exports 87k+ rows and then stops part way through the last row that is exported.
What is going on? The query that pulls the data from MSSQL is correct (I've checked).
Here's my Export file:
error_reporting(E_ALL);
ini_set('display_errors', 1);
include('DBConn.php');
include 'Helper/LogReport.php';
if(isset($_GET['Id']))
{
$id = $_GET['Id'];
$query = $conn->prepare('SELECT QName, tsql from pmdb.QDefs WHERE Id = ' . $id);
$query->execute();
$qdef = $query->fetch(PDO::FETCH_ASSOC);
}
else
{
$query = $conn->prepare("SELECT QName, tsql from pmdb.QDefs WHERE QName = '" .$TableName. "'");
$query->execute();
$qdef = $query->fetch(PDO::FETCH_ASSOC);
}
// Create and open file for writing
$filepath = 'exports/';
$filename = $qdef['QName'] . '.csv';
try
{
header('Content-Encoding: UTF-8');
header('Content-Type: text/csv; charset:UTF-8');
header('Content-Disposition: attachment; filename="' . $filename . '"');
}
catch(Exception $e)
{
echo "Something went wrong<br>";
die( print_r( $e->getMessage()));
}
//define separators
$sep = ","; //separator
$br = "\r\n"; //line break
// Use returned tsql field as query for dataset
$tsql = $qdef['tsql'];
if(isset($DataReturn))
{
if(strpos($DataReturn['Order'],'EDIT'))
{
$DataReturn['Order'] = str_replace('EDIT','Id',$DataReturn['Order']);
}
$tsql = $tsql . $DataReturn['WhereClause'] . $DataReturn['Order'] . $DataReturn['Limit'];
}
$query = $conn->prepare($tsql);
$query->execute();
// Output data to CSV file
$headers = NULL;
while ($row = $query->fetch(PDO::FETCH_ASSOC))
{
//Write column headings to file
if (is_null($headers))
{
$headers = array_keys($row);
if ($headers[0] == 'ID')
$headers[0] = 'Id';
foreach($headers as $Header)
{
echo $Header. ",";
}
echo $br;
}
//Write data
$modRow = preg_replace('/ \d{2}:\d{2}:\d{2}\.\d{3}/', '', $row);
$modRow = preg_replace( "/\r|\n/", "", $modRow );
foreach($modRow as $RowPrint)
{
echo '"' .trim(unserialize(serialize($RowPrint))). '"' .$sep;
}
echo $br;
}
I don't see anything that would stop the data stream from completing the export.
EDIT
I have tried the fputcsv() method like this:
error_reporting(E_ALL);
ini_set('display_errors', 1);
include('DBConn.php');
include 'Helper/LogReport.php';
//print_r($_GET);
if(isset($_GET['Id']))
{
$id = $_GET['Id'];
$query = $conn->prepare('SELECT QName, tsql from pmdb.QDefs WHERE Id = ' . $id);
$query->execute();
$qdef = $query->fetch(PDO::FETCH_ASSOC);
}
else
{
$query = $conn->prepare("SELECT QName, tsql from pmdb.QDefs WHERE QName = '" .$TableName. "'");
$query->execute();
$qdef = $query->fetch(PDO::FETCH_ASSOC);
}
// Create and open file for writing
$filepath = 'exports/';
$filename = $qdef['QName'] . '.csv';
try
{
$openFile = fopen($filepath . $filename,'a');
header('Content-Encoding: UTF-8');
header('Content-Type: text/csv; charset:UTF-8');
header('Content-Disposition: attachment; filename="' . $filename . '"');
}
catch(Exception $e)
{
echo "Something went wrong<br>";
die( print_r( $e->getMessage()));
}
//define separators
$sep = ","; //separator
$br = "\r\n"; //line break
// Use returned tsql field as query for dataset
$tsql = $qdef['tsql'];
if(isset($DataReturn))
{
if(strpos($DataReturn['Order'],'EDIT'))
{
$DataReturn['Order'] = str_replace('EDIT','Id',$DataReturn['Order']);
}
$tsql = $tsql . $DataReturn['WhereClause'] . $DataReturn['Order'] . $DataReturn['Limit'];
}
$query = $conn->prepare($tsql);
$query->execute();
// Output data to CSV file
$headers = NULL;
while ($row = $query->fetch(PDO::FETCH_ASSOC))
{
//Write column headings to file
if (is_null($headers))
{
$headers = array_keys($row);
if ($headers[0] == 'ID')
$headers[0] = 'Id';
fputcsv($openFile, $headers);
}
//Write data
$modRow = preg_replace('/ \d{2}:\d{2}:\d{2}\.\d{3}/', '', $row);
$modRow = preg_replace( "/\r|\n/", "", $modRow );
fputcsv($openFile, $modRow, ',','"');//print_r($modRow);
foreach($modRow as $RowPrint)
{
error_log(date("Y/m/d h:i:sa "). ' RowPrint: ' .$RowPrint. '\n',3,'C:\Temp\LogPHP.txt');
}
echo $br;
}
// Close file
fclose($openFile);
This just creates an empty file.
UPDATE
I ran a couple of reports for one that should have 103k+ rows. They both stopped between 61000 and 62000 rows. I did a character count and they both have around 40 million. I don't see anything about a 40million character limit.
I got it working and figured out how to get the fputcsv to work.
I needed to add an exit() to the end of the export. Now it not only sends all the data fputcsv works as well. I got the answer from another question that I ask about getting fputcsv to work.
I have a php script that exports a data from mysql into the csv. Everything worked fine, when the script was smaller but now, when it reaches a numerous code lines it doesn't do the job.
PROBLEM: it export csv file regularly, but all the tables results are in the first cell of excel. It is supposed to fill each cell - it should recognize in database where there is a comma, then use delimiter and split into cells separately.
So, the delimiter is not working and I don't know why. It should use commas and split it, and it should use | to split again.
This is the code:
$link = mysql_connect($host, $user, $pass) or die("Can not connect." . mysql_error());
mysql_select_db($db) or die("Can not connect.");
$result = mysql_query("SHOW COLUMNS FROM ".$table."");
$columnName = array();
if (mysql_num_rows($result) > 0)
{
while ($row = mysql_fetch_assoc($result))
{
$columnName[] = $row['Field'];
$i++;
}
}
$columnName[] .= "\n";
$needle = '|';
$values = mysql_query("SELECT * FROM ".$table." where id=".$id."");
while ($rowr = mysql_fetch_row($values))
{
for ($j=0;$j<$i;$j++)
{
$colName = $columnName[$j];
$count = strlen($rowr[$j]) - strlen(str_replace(str_split($needle), '', $rowr[$j]));
if ($count > 1)
{
for($p=0;$p<$count;$p++)
{
$colName .= ",";
}
$columnName[$j] = $colName;
$csv_output_column_names .= $columnName[$j].", ";
$csv_output_column_values .= str_replace('|',',',$rowr[$j]).", ";
}
else
{
$csv_output_column_names .= $columnName[$j].", ";
$csv_output_column_values .= $rowr[$j] .", ";
}
}
$csv_output_column_values .= "\n";
}
$csv_output = $csv_output_column_names."\n".$csv_output_column_values;
$filename = $file."_".date("Y-m-d");
header("Content-type: application/vnd.ms-excel");
header("Content-disposition: csv" . date("Y-m-d") . ".csv");
header("Content-disposition: filename=".$filename.".csv");
print $csv_output;
exit;
?>
Your issue is that you're not quoting fields as Excel expects it.
Instead of reinventing the wheel, you should use the already existing fgetcsv and fputcsv functions.
Normally these are used to write to files, but you can create a file handle to standard out so that they're printed to screen. For example:
header("Content-type: application/vnd.ms-excel");
header("Content-disposition: csv" . date("Y-m-d") . ".csv");
header("Content-disposition: filename=".$filename.".csv");
// $lines is a 2D array with all rows and their column data
// $columns is a 1D array with each row's columns (see examples from fputcsv documentation)
$out = fopen("php://stdout", "w");
foreach ($lines as $columns) { fputcsv($out, $columns); }
fclose($out);
You need to care about memory to begin with, including this solves the problem delimited CSV.
Example:
$file = new SplFileObject('php://output', 'w');
$file->fputcsv($rowr, ';', '"');
I have a mysql row with utf8_general_ci collation, when I export it to csv, instead of correct utf-8 characters I get Ć…ā€¦I etc, how to make excel understand UTF-8 encoding here is my code:
$conn = mysql_connect('localhost', 'root', 'asdfggh') or die(mysql_error());
mysql_query("SET CHARACTER SET utf8");
mysql_query("SET NAMES utf8");
mysql_select_db('table_name', $conn) or die(mysql_error($conn));
$query = sprintf('SELECT * FROM sudraba_birzs');
$result = mysql_query($query, $conn) or die(mysql_error($conn));
header('Content-Encoding: UTF-8');
header('Content-type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename="'.date("d-m-Y_H:i") . '.csv'.'"');
echo "\xef\xbb\xbf";
$row = mysql_fetch_assoc($result);
if ($row) {
echocsv(array_keys($row));
}
while ($row) {
echocsv($row);
$row = mysql_fetch_assoc($result);
}
function echocsv($fields)
{
$separator = '';
foreach ($fields as $field) {
if (preg_match('/\\r|\\n|,|"/', $field)) {
$field = '"' . str_replace('"', '""', $field) . '"';
}
echo $separator . $field;
$separator = ',';
}
echo "\r\n";
}
How to export it to get all characters display correctly (make Excel understand utf-8) and to maintain table layout too(with rows and columns)
You are generating CSV, which is basically a plain text file. There's no way to specify encoding information in such kind of files. Most text editors implement (better or worse) encoding auto-detection. Excel doesn't. Excel will simply assume ANSI when you right-click on a CSV file. (You need to use the "Open" menu in order to be prompted about encoding.)
Your only option left (apart from switching to another output format) is converting data to ANSI, either with mb_convert_encoding() or with iconv(). But now you have another problem: ANSI is not a real encoding, it basically means "whatever encoding is set in my Windows computer". You first have to find out the typical encoding most of your users have. That mostly depends on the country. For instance, many Western Europe countries use Win-1252.
I had the same problem (common problem in databases with spanish language). I wrote this and it worked:
This is a Class that connects with the database and the functions will do whatever you want using mysqli and PHP. In this case, calling this class (require or include), just use the "downloadCsv()" function.
As an example, this would be the "class.php" file:
<?php
class DB{
private $con;
//this constructor connects with the database
public function __construct(){
$this->con = new mysqli("Your_Host","Your_User","Your_Pass","Your_DatabaseName");
if($this->con->connect_errno > 0){
die('There was a problem [' . $con->connect_error . ']');
}
}
//create the function that will download a csv file from a mysqli query
public function downloadCsv(){
$count = 0;
$header = "";
$data = "";
//query
$result = $this->con->query("SELECT * FROM Your_TableName");
//count fields
$count = $result->field_count;
//columns names
$names = $result->fetch_fields();
//put column names into header
foreach($names as $value) {
$header .= $value->name.";";
}
}
//put rows from your query
while($row = $result->fetch_row()) {
$line = '';
foreach($row as $value) {
if(!isset($value) || $value == "") {
$value = ";"; //in this case, ";" separates columns
} else {
$value = str_replace('"', '""', $value);
$value = '"' . $value . '"' . ";"; //if you change the separator before, change this ";" too
}
$line .= $value;
} //end foreach
$data .= trim($line)."\n";
} //end while
//avoiding problems with data that includes "\r"
$data = str_replace("\r", "", $data);
//if empty query
if ($data == "") {
$data = "\nno matching records found\n";
}
$count = $result->field_count;
//Download csv file
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=FILENAME.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo $header."\n".$data."\n";
}
?>
After creating the "class.php" file, in this example, use that function on "download.php" file:
<?php
//call the "class.php" file
require_once 'class.php';
//instantiate DB class
$export = new DB();
//call function
$export->downloadCsv();
?>
After download, open the file with MS Excel.
I hope this help you, I think I wrote it well, I didn't feel comfortable with the text and code field.
As an alternate and much sipmler solution, you can try this, i am using it for a few years by now, and never had a problem with it.
db_connect.php
<?php
$mysqli = new mysqli($mysqli_host, $mysqli_user, $mysqli_pass, $mysqli_db);
if ($mysqli->connect_errno)
{
$debug = $debug.'<br/>Failed to connect to MySQL: (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error;
}
else
{
$debug = $debug.'<br/>Connected to '. $mysqli->host_info;
}
?>
Export function
function export($query_exp,$name)
{
require '../lib/db_config.php';
require '../lib/db_connect.php';
$filename = $name.' - '.date('Y.m.d').'.xls'; /*set desired output file name here*/
function cleanData(&$str)
{
$str = preg_replace("/\t/", "\\t", $str);
$str = preg_replace("/\r?\n/", "\\n", $str);
if(strstr($str, '"')) $str = '"' . str_replace('"', '""', $str) . '"';
if ($str=='') {$str='-';}
}
header("Content-Disposition: attachment; filename=\"$filename\"");
header("Content-Type: application/vnd.ms-excel");
$flag = false;
if ($result = $mysqli->query($query_exp))
{
if ($result->num_rows>0)
{
$result->data_seek(0);
while ($row = $result->fetch_assoc())
{
if(!$flag)
{
print implode("\t", array_keys($row)) . "\r\n";
$flag = true;
}
array_walk($row, 'cleanData');
print implode("\t", array_values($row)) . "\r\n";
}
}
else { $debug = $debug.'<br/>Empty result'; /*DEBUG*/ }
}
else { $debug = $debug.'<br/>Oups, Query error!<br/>Query: '.$query_exp.'<br/>Error: '.$mysqli->error.'.'; /*DEBUG*/ }
require '../lib/db_disconnect.php';
}
You can call the function as:
export('SELECT * FROM SAMPLE WHERE 1;','desired_file_name.extension')
Is anyone aware of a method to export specific fields from a database with custom column titles into excel from MSQL using PHP?
Where are there resources on this?
Using the PHPExcel library:
// connection with the database
$dbhost = "localhost";
$dbuser = "root";
$dbpass = "";
$dbname = "database";
mysql_connect($dbhost,$dbuser,$dbpass);
mysql_select_db($dbname);
// require the PHPExcel file
require 'Classes/PHPExcel.php';
// simple query
$query = "SELECT username,emailAdress,locationCity FROM users ORDER by id DESC";
$headings = array('User Name', 'EMail Address','City');
if ($result = mysql_query($query) or die(mysql_error())) {
// Create a new PHPExcel object
$objPHPExcel = new PHPExcel();
$objPHPExcel->getActiveSheet()->setTitle('List of Users');
$rowNumber = 1;
$col = 'A';
foreach($headings as $heading) {
$objPHPExcel->getActiveSheet()->setCellValue($col.$rowNumber,$heading);
$col++;
}
// Loop through the result set
$rowNumber = 2;
while ($row = mysql_fetch_row($result)) {
$col = 'A';
foreach($row as $cell) {
$objPHPExcel->getActiveSheet()->setCellValue($col.$rowNumber,$cell);
$col++;
}
$rowNumber++;
}
// Freeze pane so that the heading line will not scroll
$objPHPExcel->getActiveSheet()->freezePane('A2');
// Save as an Excel BIFF (xls) file
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="userList.xls"');
header('Cache-Control: max-age=0');
$objWriter->save('php://output');
exit();
}
echo 'a problem has occurred... no data retrieved from the database';
Using PHPExcel, you can also add formatting, or create workbooks with multiple worksheets, etc
Excel will happily read a CSV file as a spreadsheet. CSV is just a text format, so create some text and echo it with the appropriate content-type:
$query = "SELECT col1, col2, col3 FROM table";
$result = mysql_query($query);
$csv = '"First Column Title","Second Column Title","Third Column Title"' . "\n";
while ($row = mysql_fetch_assoc($result)) {
$csv .= '"' . str_replace('"', '""', $row['col1']) . '",';
$csv .= '"' . str_replace('"', '""', $row['col2']) . '",';
$csv .= '"' . str_replace('"', '""', $row['col3']) . '"' . "\n";
}
header("Content-type: application/vnd.ms-excel");
echo $csv;
Just do a select on the fields you want, and output the results with fields separated by commas, and each row on its own line. Ideally, should should surround each value with quotes, and addslashes() to escape any quotes in the data.
Output the result and save to a file with a name ending in .csv, and open it in Excel.
I feel like I'm making a simple mistake but I can't seem to figure out what.
I have some code for exporting a mySQL table to an Excel file.
However, when I do the export, the entire HTML source code gets exported along with my data. I open the file in Excel and my table data in there but it's also got all the HTML inside.
What could be causing all the source code to be exported along with the data?
I should mention that I'm using this code as part of a Wordpress plugin I'm writing. When I test the export outside wordpress, it works fine. But when I try to export from a Wordpress admin page, I get all the extra HTML source code.
Try this code.
$host = 'localhost';
$user = 'mysqlUser';
$pass = 'myUserPass';
$db = 'myDatabase';
$table = 'products_info';
$file = 'export';
$link = mysql_connect($host, $user, $pass) or die("Can not connect." . mysql_error());
mysql_select_db($db) or die("Can not connect.");
$res = mysql_query("SELECT * FROM $table");
// fetch a row and write the column names out to the file
$row = mysql_fetch_assoc($res);
$line = "";
$comma = "";
foreach($row as $name => $value) {
$line .= $comma . '"' . str_replace('"', '""', $name) . '"';
$comma = ",";
}
$line .= "\n";
fputs($fp, $line);
// remove the result pointer back to the start
mysql_data_seek($res, 0);
// and loop through the actual data
while($row = mysql_fetch_assoc($res)) {
$line = "";
$comma = "";
foreach($row as $value) {
$line .= $comma . '"' . str_replace('"', '""', $value) . '"';
$comma = ",";
}
$line .= "\n";
fputs($fp, $line);
}
fclose($fp);
header('Content-type: application/csv');
header('Content-Disposition: attachment; filename="export.csv"');
readfile('export.csv');
Thanks,
Kanji