|
|
@@ -591,170 +591,61 @@ class Color extends Start_Controller {
|
|
|
}
|
|
|
|
|
|
private function _ex2(){
|
|
|
+ // 关闭错误输出,避免 PHP Warning 混入 Excel 内容导致文件损坏
|
|
|
+ error_reporting(0);
|
|
|
+ ini_set('display_errors', 'Off');
|
|
|
+
|
|
|
$title = $this->input->get('title',true);
|
|
|
- $content = $this->input->get('content',true);
|
|
|
- $warehouse = $this->input->get('warehouse',true);
|
|
|
- $type = $this->input->get('type',true);
|
|
|
- $developer = $this->input->get('developer',true);
|
|
|
- $state = $this->input->get('state',true);
|
|
|
- $timetk = $this->input->get('timetk',true);
|
|
|
- $timetj = $this->input->get('timetj',true);
|
|
|
- $color = $this->input->get('color',true);
|
|
|
- $xztime = $this->input->get('xztime',true);
|
|
|
- $timetk = strtotime($timetk);
|
|
|
- $timetj = strtotime($timetj);
|
|
|
- $sid = $this->input->get('sid',true);
|
|
|
- $where = "1=1";
|
|
|
- if($title)
|
|
|
- {
|
|
|
- $where .= " and title like '%$title%'";
|
|
|
- }
|
|
|
- if($content)
|
|
|
- {
|
|
|
- $where .= " and content like '%$content%'";
|
|
|
- }
|
|
|
- if($warehouse)
|
|
|
- {
|
|
|
- $where .= " and warehouse = '$warehouse'";
|
|
|
- }
|
|
|
- if($type)
|
|
|
- {
|
|
|
- $where .= " and type = '$type'";
|
|
|
- }
|
|
|
- if($state)
|
|
|
- {
|
|
|
- $where .= " and state = '$state'";
|
|
|
- }
|
|
|
- if($color){
|
|
|
- $where .= " and color = '$color'";
|
|
|
+ $content = $this->input->get('content',true);
|
|
|
+ $warehouse = $this->input->get('warehouse',true);
|
|
|
+ $type = $this->input->get('type',true);
|
|
|
+ $developer = $this->input->get('developer',true);
|
|
|
+ $state = $this->input->get('state',true);
|
|
|
+ $timetk = $this->input->get('timetk',true);
|
|
|
+ $timetj = $this->input->get('timetj',true);
|
|
|
+ $color = $this->input->get('color',true);
|
|
|
+ $xztime = $this->input->get('xztime',true);
|
|
|
+ $timetk = strtotime($timetk);
|
|
|
+ $timetj = strtotime($timetj);
|
|
|
+ $sid = $this->input->get('sid',true);
|
|
|
+ $where = "1=1";
|
|
|
+ if($title) { $where .= " and title like '%$title%'"; }
|
|
|
+ if($content) { $where .= " and content like '%$content%'"; }
|
|
|
+ if($warehouse) { $where .= " and warehouse = '$warehouse'"; }
|
|
|
+ if($type) { $where .= " and type = '$type'"; }
|
|
|
+ if($state) { $where .= " and state = '$state'"; }
|
|
|
+ if($color) { $where .= " and color = '$color'"; }
|
|
|
+ if($developer) { $where .= " and developer = '$developer'"; }
|
|
|
+ if($timetk && $timetj){
|
|
|
+ if($xztime == 2){
|
|
|
+ $where .= " and time > '$timetk' and time < '$timetj'";
|
|
|
+ }else{
|
|
|
+ $where .= " and edittime > '$timetk' and edittime < '$timetj'";
|
|
|
}
|
|
|
- if($developer)
|
|
|
- {
|
|
|
- $where .= " and developer = '$developer'";
|
|
|
- }
|
|
|
- if($timetk && $timetj)
|
|
|
- {
|
|
|
- if($xztime == 2){
|
|
|
- $where .= " and time > '$timetk' and time < '$timetj'";
|
|
|
- }else{
|
|
|
- $where .= " and edittime > '$timetk' and edittime < '$timetj'";
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- if($sid)
|
|
|
- {
|
|
|
- $where .= " and id in (".trim($sid,',').") ";
|
|
|
- }
|
|
|
-
|
|
|
- //数据排序
|
|
|
- $order_str = "id desc";
|
|
|
+ }
|
|
|
+ if($sid) { $where .= " and id in (".trim($sid,',').") "; }
|
|
|
|
|
|
-
|
|
|
+ $order_str = "id desc";
|
|
|
+ $fields = 'id,title,state,type,color,lowe,content,gylj,scsx,img,developer,craft_process,time';
|
|
|
|
|
|
- $info_list = $this->color->find_all($where,'id,title,state,type,color,lowe,content,gylj,scsx,img,developer,craft_process,time');
|
|
|
- foreach ($info_list as $key=>$value)
|
|
|
- {
|
|
|
- if(empty($value['developer'])){
|
|
|
- $info_list[$key]['developer'] = '';
|
|
|
- }
|
|
|
- if(empty($value['craft_process'])){
|
|
|
- $info_list[$key]['craft_process'] = '';
|
|
|
- }
|
|
|
-
|
|
|
- if($value['state'] == 1)
|
|
|
- {
|
|
|
- $info_list[$key]['state'] = '在售款';
|
|
|
- }
|
|
|
- else if($value['state'] == 2)
|
|
|
- {
|
|
|
- $info_list[$key]['state'] = '已停售';
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- $info_list[$key]['state'] = '未选择';
|
|
|
- }
|
|
|
-
|
|
|
- if($value['type'] == 1)
|
|
|
- {
|
|
|
- $info_list[$key]['type'] = '编号款配图';
|
|
|
- }
|
|
|
- else if($value['type'] == 2)
|
|
|
- {
|
|
|
- $info_list[$key]['type'] = '颜色配图';
|
|
|
- }
|
|
|
- else if($value['type'] == 3)
|
|
|
- {
|
|
|
- $info_list[$key]['type'] = '曲度配图';
|
|
|
- }
|
|
|
- else if($value['type'] == 4)
|
|
|
- {
|
|
|
- $info_list[$key]['type'] = '编号款配图';
|
|
|
- }
|
|
|
- else if($value['type'] == 5){
|
|
|
- $info_list[$key]['type'] = '化纤编号款';
|
|
|
- }
|
|
|
- else if($value['type'] == 6){
|
|
|
- $info_list[$key]['type'] = '化纤颜色';
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- $info_list[$key]['type'] = '未选择';
|
|
|
- }
|
|
|
-
|
|
|
- $colorimg = explode('|',$value['img']);
|
|
|
- $v = $colorimg[0];
|
|
|
- $img_list = [];
|
|
|
- $str_img = '<table class="img_container" width="100%" cellspacing="0" cellpadding="0"><tr>';
|
|
|
- foreach ($colorimg as $k=>$v)
|
|
|
- {
|
|
|
-
|
|
|
- $lx = explode(".",$v);
|
|
|
- $lx = strtolower(end($lx));
|
|
|
- if($lx == "3gp" || $lx == "rmvb" || $lx == "flv" || $lx == "wmv" || $lx == "avi" || $lx == "mkv" || $lx == "wav" || $lx == "mp4")
|
|
|
- {
|
|
|
- $info_list[$key]['img'] = '暂不支持视频';
|
|
|
- }
|
|
|
- else if($v != '')
|
|
|
- {
|
|
|
- $imageData = file_get_contents($v);
|
|
|
- $mimeType = "image/png";
|
|
|
- if(strpos($v,".jpg") !== false){
|
|
|
- $mimeType = "image/jpeg";
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- // 转换为 Base64
|
|
|
- $base64 = base64_encode($imageData);
|
|
|
-
|
|
|
- // 构建 Data URI
|
|
|
- $dataUri = 'data:' . $mimeType . ';base64,' . $base64;
|
|
|
-
|
|
|
- //$info_list[$key]['img'] = "<img width='170' src='".$dataUri."'>";
|
|
|
- $str_img .= "<td width='25%' style='width:25%;color:#fff'>新品/新色配图新品/新色配图<img width='170' src='".$dataUri."'></td>";
|
|
|
- }else{
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
- $str_img .= '</tr></table>';
|
|
|
- $info_list[$key]['img'] = $str_img;
|
|
|
- $info_list[$key]['time'] = date('Y-m-d H:i:s',$value['time']);
|
|
|
- $info_list[$key]['gylj'] = empty($value['gylj'])?'':$value['gylj'];
|
|
|
- $info_list[$key]['scsx'] = empty($value['scsx'])?0:$value['scsx'];
|
|
|
- unset($info_list[$key]['id']);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
+ // 状态/类型映射表
|
|
|
+ $state_map = [1 => '在售款', 2 => '已停售'];
|
|
|
+ $type_map = [1 => '编号款配图', 2 => '颜色配图', 3 => '曲度配图', 4 => '编号款配图', 5 => '化纤编号款', 6 => '化纤颜色'];
|
|
|
+ $video_ext = ['3gp'=>1,'rmvb'=>1,'flv'=>1,'wmv'=>1,'avi'=>1,'mkv'=>1,'wav'=>1,'mp4'=>1];
|
|
|
|
|
|
- $title = "新品/新色配图";
|
|
|
+ $filename = date("Y-m-d") . "新品-新色配图.xls";
|
|
|
|
|
|
+ // 先输出 HTTP 头
|
|
|
+ header("Content-Type: application/vnd.ms-excel; charset=utf-8");
|
|
|
+ header("Content-Disposition: attachment; filename=".$filename);
|
|
|
+ header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
|
|
|
+ header("Pragma: no-cache");
|
|
|
+ header("Expires: 0");
|
|
|
|
|
|
- $filename = date("Y-m-d") . $title.".xls";
|
|
|
- $str = "<html xmlns:x=\"urn:schemas-microsoft-com:office:excel\">
|
|
|
+ // 输出 Excel HTML 头部
|
|
|
+ echo '<html xmlns:x="urn:schemas-microsoft-com:office:excel">
|
|
|
<head>
|
|
|
- <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">
|
|
|
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
|
<!--[if gte mso 9]>
|
|
|
<xml>
|
|
|
<x:ExcelWorkbook>
|
|
|
@@ -773,87 +664,155 @@ class Color extends Start_Controller {
|
|
|
<![endif]-->
|
|
|
<style>
|
|
|
tr { mso-height-source: auto; }
|
|
|
- .fixed-height {
|
|
|
- height: 220px;
|
|
|
- mso-height-source: userset;
|
|
|
+ .fixed-height { height: 220px; mso-height-source: userset; }
|
|
|
+ .img_container { width: 100%; mso-table-lspace: 0pt; mso-table-rspace: 0pt; border-collapse: collapse; table-layout: fixed; }
|
|
|
+ .img_container td { width: 25%; vertical-align: top; text-align: center; padding: 2px; mso-cellspacing: 0pt; mso-padding-alt: 0pt 0pt 0pt 0pt; overflow: hidden; }
|
|
|
+ .img_container img { width: 100%; max-width: 170px; max-height: 200px; height: auto; display: block; margin: 0 auto; mso-width-percent: 1000; mso-height-relative: page; }
|
|
|
+ .img_container[width] { mso-width-percent: 1000; }
|
|
|
+ .img_container td[width="25%"] { width: 25% !important; mso-width-percent: 250; }
|
|
|
+ </style>
|
|
|
+ </head>
|
|
|
+ <body>';
|
|
|
+ echo '<table border="1" cellspacing="0" style="border-collapse: collapse; font-family: Microsoft Yahei; font-size: 13px;"><col width="150"><col width="80"><col width="100"><col width="50"><col width="50"><col width="150"><col width="80"><col width="100"><col width="120"><col width="600">';
|
|
|
+ echo '<tr><td>标题</td><td>是否在售</td><td>配图类型</td><td>色号</td><td>曲度</td><td>备注</td><td>工艺路径</td><td>生产时效</td><td>开发人</td><td>重要信息提醒</td><td>添加时间</td><td width="600">图片</td></tr>';
|
|
|
+
|
|
|
+ // ========== 核心优化:分批查询 + curl_multi 并发下载 + 流式输出 ==========
|
|
|
+ $batch_size = 50;
|
|
|
+ $offset = 0;
|
|
|
+ $img_cache = []; // url => dataUri 内存缓存,跨批次复用
|
|
|
+
|
|
|
+ while (true) {
|
|
|
+ $batch = $this->color->find_all($where, $fields, $order_str, $offset, $batch_size);
|
|
|
+ if (empty($batch)) break;
|
|
|
+
|
|
|
+ // 1. 收集本批次所有图片 URL
|
|
|
+ $batch_urls = [];
|
|
|
+ foreach ($batch as $row) {
|
|
|
+ foreach (explode('|', $row['img']) as $url) {
|
|
|
+ $url = trim($url);
|
|
|
+ if ($url !== '' && !isset($img_cache[$url])) {
|
|
|
+ $batch_urls[$url] = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- /* Excel兼容的图片布局方案 */
|
|
|
- .img_container {
|
|
|
- width: 100%;
|
|
|
- mso-table-lspace: 0pt;
|
|
|
- mso-table-rspace: 0pt;
|
|
|
- border-collapse: collapse;
|
|
|
- table-layout: fixed; /* 关键:固定表格布局 */
|
|
|
+ $batch_urls = array_keys($batch_urls);
|
|
|
+
|
|
|
+ // 2. 并发下载未被缓存的图片
|
|
|
+ if (!empty($batch_urls)) {
|
|
|
+ $this->_curl_multi_fetch($batch_urls, $img_cache);
|
|
|
}
|
|
|
-
|
|
|
- .img_container td {
|
|
|
- width: 25%; /* 每行最多4张图片 */
|
|
|
- vertical-align: top;
|
|
|
- text-align: center;
|
|
|
- padding: 2px;
|
|
|
- /* 添加这些以确保宽度正确 */
|
|
|
- mso-cellspacing: 0pt;
|
|
|
- mso-padding-alt: 0pt 0pt 0pt 0pt;
|
|
|
- overflow: hidden;
|
|
|
+
|
|
|
+ // 3. 处理并输出本批次每一行
|
|
|
+ foreach ($batch as $value) {
|
|
|
+ $value['developer'] = empty($value['developer']) ? '' : $value['developer'];
|
|
|
+ $value['craft_process'] = empty($value['craft_process']) ? '' : $value['craft_process'];
|
|
|
+ $value['state'] = isset($state_map[$value['state']]) ? $state_map[$value['state']] : '未选择';
|
|
|
+ $value['type'] = isset($type_map[$value['type']]) ? $type_map[$value['type']] : '未选择';
|
|
|
+ $value['time'] = date('Y-m-d H:i:s', $value['time']);
|
|
|
+ $value['gylj'] = empty($value['gylj']) ? '' : $value['gylj'];
|
|
|
+ $value['scsx'] = empty($value['scsx']) ? 0 : $value['scsx'];
|
|
|
+
|
|
|
+ // 构建图片 HTML
|
|
|
+ $colorimg = explode('|', $value['img']);
|
|
|
+ $str_img = '<table class="img_container" width="100%" cellspacing="0" cellpadding="0"><tr>';
|
|
|
+ foreach ($colorimg as $v) {
|
|
|
+ $v = trim($v);
|
|
|
+ if ($v === '') continue;
|
|
|
+ $lx = strtolower(pathinfo(parse_url($v, PHP_URL_PATH), PATHINFO_EXTENSION));
|
|
|
+ if (isset($video_ext[$lx])) {
|
|
|
+ $str_img = '暂不支持视频';
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (isset($img_cache[$v])) {
|
|
|
+ $str_img .= '<td width="25%" style="width:25%;color:#fff">新品/新色配图新品/新色配图<img width="170" src="'.$img_cache[$v].'"></td>';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ($str_img !== '暂不支持视频') {
|
|
|
+ $str_img .= '</tr></table>';
|
|
|
+ }
|
|
|
+ $value['img'] = $str_img;
|
|
|
+
|
|
|
+ echo '<tr class="fixed-height">';
|
|
|
+ echo '<td>'.$value['title'].'</td>';
|
|
|
+ echo '<td>'.$value['state'].'</td>';
|
|
|
+ echo '<td>'.$value['type'].'</td>';
|
|
|
+ echo '<td>'.$value['color'].'</td>';
|
|
|
+ echo '<td>'.$value['lowe'].'</td>';
|
|
|
+ echo '<td>'.$value['content'].'</td>';
|
|
|
+ echo '<td>'.$value['gylj'].'</td>';
|
|
|
+ echo '<td>'.$value['scsx'].'</td>';
|
|
|
+ echo '<td>'.$value['developer'].'</td>';
|
|
|
+ echo '<td>'.$value['craft_process'].'</td>';
|
|
|
+ echo '<td>'.$value['time'].'</td>';
|
|
|
+ echo '<td width="600">'.$value['img'].'</td>';
|
|
|
+ echo '</tr>';
|
|
|
}
|
|
|
-
|
|
|
- .img_container img {
|
|
|
- width: 100%; /* 图片填充单元格宽度 */
|
|
|
- max-width: 170px; /* 最大宽度限制 */
|
|
|
- max-height: 200px;
|
|
|
- height: auto;
|
|
|
- display: block;
|
|
|
- margin: 0 auto;
|
|
|
- /* 添加这些以增强兼容性 */
|
|
|
- mso-width-percent: 1000; /* 100%的百分比表示 */
|
|
|
- mso-height-relative: page;
|
|
|
+
|
|
|
+ unset($batch, $batch_urls);
|
|
|
+ $offset += $batch_size;
|
|
|
+
|
|
|
+ // 及时刷新输出缓冲,释放内存
|
|
|
+ if (ob_get_level()) {
|
|
|
+ ob_flush();
|
|
|
}
|
|
|
-
|
|
|
- /* 关键:确保单元格宽度精确计算 */
|
|
|
- .img_container[width] {
|
|
|
- mso-width-percent: 1000;
|
|
|
+ flush();
|
|
|
+ }
|
|
|
+
|
|
|
+ echo '</table></body></html>';
|
|
|
+ exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * curl_multi 并发下载图片,结果写入 $cache(引用传递,跨批次复用)
|
|
|
+ * @param array $urls 待下载的 URL 列表
|
|
|
+ * @param array &$cache url => dataUri 的缓存 map
|
|
|
+ */
|
|
|
+ private function _curl_multi_fetch($urls, &$cache) {
|
|
|
+ $chunk_size = 20; // 每批并发 20 个请求
|
|
|
+ $chunks = array_chunk($urls, $chunk_size);
|
|
|
+
|
|
|
+ foreach ($chunks as $chunk) {
|
|
|
+ $mh = curl_multi_init();
|
|
|
+ $handles = [];
|
|
|
+
|
|
|
+ foreach ($chunk as $i => $url) {
|
|
|
+ $ch = curl_init($url);
|
|
|
+ curl_setopt_array($ch, [
|
|
|
+ CURLOPT_RETURNTRANSFER => true,
|
|
|
+ CURLOPT_TIMEOUT => 10,
|
|
|
+ CURLOPT_CONNECTTIMEOUT => 5,
|
|
|
+ CURLOPT_FOLLOWLOCATION => true,
|
|
|
+ CURLOPT_MAXREDIRS => 3,
|
|
|
+ CURLOPT_SSL_VERIFYPEER => false,
|
|
|
+ CURLOPT_SSL_VERIFYHOST => false,
|
|
|
+ ]);
|
|
|
+ curl_multi_add_handle($mh, $ch);
|
|
|
+ $handles[$i] = [$ch, $url];
|
|
|
}
|
|
|
- .img_container td[width='25%'] {
|
|
|
- width: 25% !important;
|
|
|
- mso-width-percent: 250; /* 25%的百分比表示 */
|
|
|
+
|
|
|
+ // 执行并发请求
|
|
|
+ do {
|
|
|
+ $status = curl_multi_exec($mh, $running);
|
|
|
+ if ($running > 0) {
|
|
|
+ curl_multi_select($mh);
|
|
|
+ }
|
|
|
+ } while ($running > 0 && $status === CURLM_OK);
|
|
|
+
|
|
|
+ // 收集结果
|
|
|
+ foreach ($handles as $item) {
|
|
|
+ list($ch, $url) = $item;
|
|
|
+ $data = curl_multi_getcontent($ch);
|
|
|
+ if ($data !== false && strlen($data) > 0) {
|
|
|
+ $ext = strtolower(pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_EXTENSION));
|
|
|
+ $mime = ($ext === 'jpg' || $ext === 'jpeg') ? 'image/jpeg' : 'image/png';
|
|
|
+ $cache[$url] = 'data:' . $mime . ';base64,' . base64_encode($data);
|
|
|
+ }
|
|
|
+ curl_multi_remove_handle($mh, $ch);
|
|
|
+ curl_close($ch);
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
- </style>
|
|
|
- </head>
|
|
|
- <body>";
|
|
|
-
|
|
|
- $str .= "<table border='1' cellspacing='0' style='border-collapse: collapse; font-family: Microsoft Yahei; font-size: 13px;'><col width='150'><col width='80'><col width='100'><col width='50'><col width='50'><col width='150'><col width='80'><col width='100'><col width='120'><col width='600'> ";
|
|
|
- $str .= "<tr >"; // 应用固定高度类
|
|
|
- $str .= "<td>标题</td><td>是否在售</td><td>配图类型</td><td>色号</td><td>曲度</td><td>备注</td><td>工艺路径</td><td>生产时效</td><td>开发人</td><td>重要信息提醒</td><td>添加时间</td><td width='600'>图片</td>";
|
|
|
- $str .= "</tr>";
|
|
|
- foreach($info_list as $key => $value){
|
|
|
- $str .= "<tr class='fixed-height'>"; // 应用固定高度类
|
|
|
- $str .= "<td>".$value['title']."</td>";
|
|
|
- $str .= "<td>".$value['state']."</td>";
|
|
|
- $str .= "<td>".$value['type']."</td>";
|
|
|
- $str .= "<td>".$value['color']."</td>";
|
|
|
- $str .= "<td>".$value['lowe']."</td>";
|
|
|
- $str .= "<td>".$value['content']."</td>";
|
|
|
- $str .= "<td>".$value['gylj']."</td>";
|
|
|
- $str .= "<td>".$value['scsx']."</td>";
|
|
|
- $str .= "<td>".$value['developer']."</td>";
|
|
|
- $str .= "<td>".$value['craft_process']."</td>";
|
|
|
- $str .= "<td>".$value['time']."</td>";
|
|
|
- $str .= "<td width='600'>".$value['img']."</td>";
|
|
|
- $str .= "</tr>";
|
|
|
+
|
|
|
+ curl_multi_close($mh);
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
- $str .= "</table></body></html>";
|
|
|
-
|
|
|
- header("Content-Type: application/vnd.ms-excel; charset=utf-8");
|
|
|
- header("Content-Disposition: attachment; filename=".$filename);
|
|
|
- header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
|
|
|
- header("Pragma: no-cache");
|
|
|
- header("Expires: 0");
|
|
|
- exit($str);
|
|
|
}
|
|
|
|
|
|
|