MySQL-不依赖类库的导出MySQL数据到Excel

MySQL-不依赖类库的导出MySQL数据到Excel

夜无邪 发布于 2017-03-15 字数 413 浏览 1256 回复 3

首先说明下问题的需求,可能社区里有题目类似的问题,但是我要说明下我的需求是不同的,所以希望大家慎票!
经常会碰到需要从数据库中导出数据到Excel文件,
用一些开源的类库,
比如PHPExcel,
确实比较容易实现,
但对大量数据的支持很不好,
很容易到达PHP内存使用上限。

我这里希望大家能提供,简单易用,非常节省内存,不依赖第三方类库的怎么一个程序。
望各位赐教!

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

归属感 2017-07-13 3 楼

自己收藏的一个处理EXCEL文件的类,直接调用即可:

 <?php
class ExcelUtil{

var $header = "<?xml version="1.0" encoding="UTF-8"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">";

var $footer = "</Workbook>";
var $lines = array();
var $worksheet_title = "Table1";

function putRow ($index, $array) {
// 初始化数组数据的最大长度
$maxMerge = 1;

// 计算数组数据的最大长度
foreach ($array as $key=>$value) {
if (is_array($value) && count($value) > $maxMerge) {
$maxMerge = count($value);
}
}

for ($i=0; $i<$maxMerge; $i++) {
// 初始化单元格
$cells = "";
foreach ($array as $key=>$value) {

// 是数组
if (is_array($value)) {
if (isset($value[$i])) {
if(is_numeric($value[$i])) {
// 防止首字母为 0 时生成 excel 后 0 丢失
if(substr($value[$i], 0, 1) == 0 || strlen($value[$i]) >= 12) {
$cells .= "<Cell><Data ss:Type="String">" . $value[$i] . "</Data></Cell>n";
} else {
$cells .= "<Cell><Data ss:Type="Number">" . $value[$i] . "</Data></Cell>n";
}
} else {
$cells .= "<Cell><Data ss:Type="String">" . $value[$i] . "</Data></Cell>n";
}
}
} // start else

// 不是数组
else {
if ($i == 0) {
if(is_numeric($value)) {
// 防止首字母为 0 时生成 excel 后 0 丢失
if(substr($value, 0, 1) == 0 || strlen($value) >= 12) {
$cells .= "<Cell><Data ss:Type="String">" . $value . "</Data></Cell>n";
} else {
$cells .= "<Cell><Data ss:Type="Number">" . $value . "</Data></Cell>n";
}
} else {
$cells .= "<Cell><Data ss:Type="String">" . $value . "</Data></Cell>n";
} // end if(is_numeric($value))
} else {
$cells .= "<Cell><Data ss:Type="String"></Data></Cell>n";
} // end if ($i == 0)
} // end if (is_array($value))
} // end foreach ($array as $key=>$value)

$this->lines[] = "<Row>n" . $cells . "</Row>n";

} // end for ($i=0; $i<$maxMerge; $i++)
}

function putData ($array) {
foreach ($array as $k=>$v) {
$this->putRow ($k, $v);
}
}

function getExcel ($filename) {
header("Content-Type: application/vnd.ms-excel; charset=UTF-8");
header("Content-Disposition: inline; filename="" . $filename . ".xls"");

echo stripslashes ($this->header);
echo "n<Worksheet ss:Name="" . $this->worksheet_title . "">n<Table>n";
echo "<Column ss:Index="1" ss:AutoFitWidth="0" ss:Width="110"/>n";
echo implode ("n", $this->lines);
echo "</Table>n</Worksheet>n";
echo $this->footer;
}
}

?>

虐人心 2017-05-02 2 楼

不用那么复杂,我以前一般在linux下执行这样的命令导出数据:

/usr/bin/mysql --default-character-set=utf8 -uroot -p"123456" -e"select * from test_db.test_table">/tmp/1.xls

就能把test_db库的test_table表数据导出,文件名直接命名成*.xls,使用excle就能打开,而且生成的xls文件很小。

甜柠檬 2017-04-10 1 楼

简单易用,非常节省内存,不依赖第三方类库:

<?php
// 输出Excel文件头,可把user.csv换成你要的文件名
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="user.csv"');
header('Cache-Control: max-age=0');

// 从数据库中获取数据,为了节省内存,不要把数据一次性读到内存,从句柄中一行一行读即可
$sql = 'select * from tbl where ……';
$stmt = $db->query($sql);

// 打开PHP文件句柄,php://output 表示直接输出到浏览器
$fp = fopen('php://output', 'a');

// 输出Excel列名信息
$head = array('姓名', '性别', '年龄', 'Email', '电话', '……');
foreach ($head as $i => $v) {
// CSV的Excel支持GBK编码,一定要转换,否则乱码
$head[$i] = iconv('utf-8', 'gbk', $v);
}

// 将数据通过fputcsv写到文件句柄
fputcsv($fp, $head);

// 计数器
$cnt = 0;
// 每隔$limit行,刷新一下输出buffer,不要太大,也不要太小
$limit = 100000;

// 逐行取出数据,不浪费内存
while ($row = $stmt->fetch(Zend_Db::FETCH_NUM)) {

$cnt ++;
if ($limit == $cnt) { //刷新一下输出buffer,防止由于数据过多造成问题
ob_flush();
flush();
$cnt = 0;
}

foreach ($row as $i => $v) {
$row[$i] = iconv('utf-8', 'gbk', $v);
}
fputcsv($fp, $row);
}