前言
有时候我们经常需要用到批量导出(或下载)数据库记录的功能,最常见的就是导出Excel方便用户查看。
第一种:在前端导出
使用a标签下载。先读取记录显示在表格中,再把表格数据导出到excel。
tableToExcel(table,name) //函数调用 (table:要导出的表ID name:导出的文件名)
var tableToExcel = (function() {
var uri = 'data:application/vnd.ms-excel;base64,',
//格式化导出表格的样式
template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel"'+
'xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet>'
+'<x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets>'
+'</x:ExcelWorkbook></xml><![endif]-->'+
' <style type="text/css">'+
'.excelTable {'+
'border-collapse:collapse;'+
' border:thin solid #999; '+
'}'+
' .excelTable th {'+
' border: thin solid #999;'+
' padding:20px;'+
' text-align: center;'+
' border-top: thin solid #999;'+
' background-color: #E6E6E6;'+
' }'+
' .excelTable td{'+
' border:thin solid #999;'+
' padding:2px 5px;'+
' text-align: center;'+
' }</style>'+
'</head><body ><table class="excelTable">{table}</table></body></html>',
base64 = function(s) { return window.btoa(unescape(encodeURIComponent(s))) },
format = function(s, c) {
return s.replace(/{(\w+)}/g,
function(m, p) { return c[p]; }) }
return function(table, name) {
if(name.length == 0){name='导出Excel信息';}
if(select=='tableid'){
/*表格id传入,代码 */
if (!table.nodeType) table = document.getElementById(table)
var ctx = {worksheet: name || 'Worksheet', table: table.innerHTML}
}
//window.location.href = uri + base64(format(template, ctx))
var downloadLink = document.createElement("A");
downloadLink.href = uri + base64(format(template, ctx));
downloadLink.download = name +'.xls';
// downloadLink.download = name + '_' + formatTime(new Date(new Date().getTime()),'yyyy_mm_dd hh:ii:ss')+'.xls';
downloadLink.target = '_blank';
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
}
})()
第二种:后端直接读取并下载到客户端
通过PHP输出流方式导出csv。
<?php
header('Access-Control-Allow-Origin:*');//允许所有来源访问
$headArr=array("AAA","BBB","CCC"); //模拟表头数据数组
$data=array(array("1","2","3"),array("11","22","33"),array("111","222","333")); //模拟表格数据
exportToExcel("ceshi", $headArr, $data); //导出数据
/**导出api**/
function exportToExcel($fileName = '', $headArr = [], $data = []){
ini_set('memory_limit','1024M'); //设置程序运行的内存
ini_set('max_execution_time',0); //设置程序的执行时间,0为无上限
ob_end_clean(); //清除内存
ob_start();
header("Content-Type: text/csv");
header("Content-Disposition:filename=".$fileName.'.csv');
$fp=fopen('php://output','w');
fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
fputcsv($fp,$headArr);
$index = 0;
foreach ($data as $item) {
if($index==1000){ //每次写入1000条数据清除内存
$index=0;
ob_flush();//清除内存
flush();
}
$index++;
fputcsv($fp,$item);
}
ob_flush();
flush();
ob_end_clean();
exit();
}
?>
第二种:后端先读取存储到本地,再下载客户端
后端先读取存储csv格式文件到本地,再下载客户端,下载完删除文件。
<?php
$file_name = "res.csv"; //下载文件名
$file_dir = "/var/www/html/vue_data_manager/userdata/"; //下载文件存放目录
$headArr=array("AAA","BBB","CCC"); /**模拟字段名数组 */
$data=array(array("1","2","3"),array("11","22","33"),array("111","222","333")); /**模拟表数据 */
/*-----------------------------------------------导出csv到本地----------------------------------------*/
createcsv($headArr,$data);/**调用函数,生成csv文件 */
/*-----------------------------------------------PHP输出流下载---------------------------------------*/
// //检查文件是否存在
if (! file_exists ( $file_dir . $file_name )) {
header('HTTP/1.1 404 NOT FOUND');
} else {
//以只读和二进制模式打开文件
$file = fopen ( $file_dir . $file_name, "rb" );
//告诉浏览器这是一个文件流格式的文件
Header ( "Content-type: application/octet-stream" );
//请求范围的度量单位
Header ( "Accept-Ranges: bytes" );
//Content-Length是指定包含于请求或响应中数据的字节长度
Header ( "Accept-Length: " . filesize ( $file_dir . $file_name ) );
//用来告诉浏览器,文件是可以当做附件被下载,下载后的文件名称为$file_name该变量的值。
Header ( "Content-Disposition: attachment; filename=" . $file_name );
//读取文件内容并直接输出到浏览器
echo fread( $file, filesize ( $file_dir . $file_name ) );
fclose ( $file );
}
unlink($file); //下载完成删除文件
/*--------------------------------------------------功能函数--------------------------------------------*/
/**createcsv 生成csv函数 */
function createcsv( $csv_header ,$csv_body)
{
/**
* 开始生成
* 1. 首先将数组拆分成以逗号(注意需要英文)分割的字符串
* 2. 然后加上每行的换行符号,这里建议直接使用PHP的预定义
* 常量PHP_EOL
* 3. 最后写入文件
*/
// 打开文件资源,不存在则创建
global $file_dir;
global $file_name ;
$fp = fopen($file_dir . $file_name ,'a');
// 处理头部标题
$header =implode(',', $csv_header). PHP_EOL;
// 处理内容
$content = '';
foreach ($csv_body as $k => $v) {
$content .= implode(',', $v) . PHP_EOL;
}
$csv=$header.$content;
// 写入并关闭资源
fwrite($fp, $csv);
fclose($fp);
}