1、php代碼
/**
* 分頁導出數據(老是順序導出).
* 返回的是 json, 由前端 js 生成 csv/xls 文件.
* @param int $page 當前頁數
* @param int $limit 當前導出的記錄數目 (這個值不能太大, 不然會形成內存超出限制)
*/
public function export_json($page = 1, $limit = 2000)
{
$this->checkIndexPermission();
if (!$this->admin->canExportGoods()) {
exit;
}
$exportType = null;
$goods = D('Goods');
$where = $this->getSearchOptions();
$count = $goods->alias('a')->where($where)->count();
$totalPage = ceil($count / $limit);
$list = $goods->alias('a')
->join('LEFT JOIN goods_trace b ON a.id = b.gid')
->field('a.*,b.record_time')
->where($where)
->page($page, $limit)->order('a.id desc')->select();
$titles = $this->getExportFieldNames($exportType);
$rows = $this->exportToArray($list);
$data = array(
'titles' => array_values($titles), // 標題
'rows' => $rows, // 數據列表
'percentage' => (int)(($page / $totalPage) * 100), // 當前總進度
);
// 若是不是最後一頁, 就加一個 next_url 的字段, 前端根據這個字段繼續請求下一頁數據
if ($page < $totalPage) {
$search = I('get.');
$search['page'] = $page + 1;
$data['next_url'] = U('export_json', $search);
}
$this->ajaxReturn($data);
}
複製代碼
/***
* 導出字段名稱
*/
public function getExportFieldNames()
{
$allFields = array(
// 字段名 => 標題名稱
'id' => '訂單id',
'dian' => '店鋪',
'utime' => '進店時間',
'wang' => '網銷',
'name' => '客戶姓名',
'phone' => '客戶電話',
'name1' => '客戶姓名1',
'phone1' => '客戶電話1',
'wx' => '微信',
'is_contacted' => '是否聯繫',
'men' => '門市',
'record_time' => '走單時間',
'jiage' => '標準套系',
'sfje' => '實付金額',
'kefu' => '客服',
'beizhu' => '備註',
'ctime' => '錄入時間',
);
return $allFields;
}
複製代碼
/**
* 獲取 字段映射 數組.
* [數據庫中的字段名 => 導出的字段名]
* @return array
*/
public function exportToArray($list)
{
$res = array();
foreach ($list as $key=>$data) {
$res[$key] = array_values(array(
'id' => $data['id'],
'dian' => $data['dian'],
'utime' => $data['utime'],
'wang' => $data['wang'],
'name' => $data['name'],
'phone' => $data['phone'],
'name1' => $data['name1'],
'phone1' => $data['phone1'],
'wx' => $data['wx'],
'is_contacted' => $data['is_contacted'] == 1 ? '是' : '否',
'men' => $data['men'],
'record_time' => $data['record_time'],
'jiage' => $data['jiage'],
'sfje' => $data['sfje'],
'kefu' => $data['kefu'],
'beizhu' => $data['beizhu'],
'ctime' => $data['ctime'],
));
}
return $res;
}
複製代碼
2、html代碼
<a id="export-data-btn" class="btn btn-warning" data-href="{:U('keyun/list/export_json', array_merge($search_options))}">數據導出</a>
<div class="modal fade" id="export-modal" tabindex="-1" role="dialog" data-backdrop="static">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">數據導出</h4>
</div>
<div class="modal-body">
<p>數據導出中, 請勿刷新或關閉瀏覽器</p>
<div class="progress">
<div id="export-progress" class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0"
aria-valuemax="100" style="width: 0%;">
</div>
</div>
</div>
</div>
</div>
</div>
<script>
$(function () {
$('#export-data-btn').click(function () {
var url = $(this).data('href');
var fetched_data = {
rows: []
};
var hint = $('#export-modal');
hint.modal('show');
fetchDataAndExport(url, fetched_data);
// 分頁獲取數據, 並導出
function fetchDataAndExport(url, data, failed) {
if (!failed) {
failed = 0;
}
$.get(url).done(function (res) {
if (res.titles) {
data.titles = res.titles
}
if (res.rows) {
data.rows = $.merge(data.rows, res.rows);
}
if (res.next_url) { // 尚未完成, 繼續獲取數據
fetchDataAndExport(res.next_url, data, failed)
} else { // 已經完成
var date = new Date();
var datetime = date.getFullYear() + '-' + date.getMonth() + '-' + date.getDate();
download(generateCSV(data), datetime + '.xls', 'application/vnd.ms-excel')
setTimeout(function () {
hint.modal('hide')
}, 1000)
}
$('#export-progress').css('width', res.percentage + '%');
}).fail(function () {
failed++;
// 整個過程容許失敗 5次, 若是超過 5次, 終止
if (failed > 5) {
hint.modal('hide');
alert('導出失敗, 獲取數據失敗!')
} else {
// 重試
fetchDataAndExport(url, data, failed)
}
})
}
// 直接用 js 生成(保存)文件
function download(data, filename, type) {
var file = new Blob([data], {type: type});
// IE10+
if (window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(file, filename);
} else { // Others
var a = document.createElement("a"),
url = URL.createObjectURL(file);
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
setTimeout(function () {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 0);
}
}
// 返回字符串
function generateCSV(data) {
var content = "\ufeff"; // BOM頭, 防止中文亂碼
if (data.titles) {
content += generateRow(data.titles);
}
for (var i in data.rows) {
content += generateRow(data.rows[i])
}
return content
}
function generateRow(row) {
var str = '';
for (var i = 0; i < row.length; i++) {
var val = row[i] === null ? '' : row[i];
if (i === 0) {
str = val
} else {
str = str + ',' + val
}
}
return str + '\r\n';
}
});
})
</script>
複製代碼