·设为首页收藏本站📧邮箱修改🎁免费下载专区📒收藏夹👽聊天室📱AI智能体
返回列表 发布新帖

[phpoffice]导出excel时带上图片,通用方法

198 1

马上注册,免费下载更多dz插件网资源。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
最近运营的一些产品需求,总是要求有商品的地方要把商品图片一块导出到excel。所以写了一个功能相对通用的方法。

首先先将phpoffice必须要用到的命名空间引入进来:
  1. use PhpOffice\PhpSpreadsheet\Exception;
  2. use PhpOffice\PhpSpreadsheet\IOFactory;
  3. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  4. use PhpOffice\PhpSpreadsheet\Style\Fill;
  5. use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
  6. use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException;
  7. use PhpOffice\PhpSpreadsheet\style\Border;
  8. use PhpOffice\PhpSpreadsheet\style\Alignment;
  9. use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
复制代码

调用方法:
[phpoffice]导出excel时带上图片,通用方法 导出,excel,图片,通用,通用方法

exportNew方法核心代码:
  1.     exportNew(array $title, array $body, string $filename='', array $ext=[],  string $export_type='xlsx')
  2.     {
  3.         if(empty($title)){
  4.             exit('表头数据为空');
  5.         }
  6.         if(empty($body)){
  7.             exit('导出数据为空');
  8.         }
  9.         $title1 = array_keys($title);//字段名称
  10.         $title2 = array_values($title);//列表头
  11.         //生成列对应的数据字段名称
  12.         foreach($title1 as $k => $v){
  13.             $letter = intToChr($k);
  14.             $title1_new[$letter] = $v;
  15.         }
  16.         unset($title1);
  17.         //生成excel的表头
  18.         foreach($title2 as $k => $v){
  19.             $letter = intToChr($k);
  20.             $title2_new[$letter] = $v;
  21.         }
  22.         unset($title2);
  23.         //超大数据导出
  24.         set_time_limit(0);
  25.         //使用模板
  26.         $spreadsheet = new Spreadsheet();
  27.         //表格对象
  28.         $worksheet = $spreadsheet->getActiveSheet();
  29.         //画表头
  30.         $startRow  = 1;
  31.         foreach($title2_new as $k => $v){
  32.             $width = 12;
  33.             if(!empty($ext['column_width'])   && is_array($ext['column_width'])  ){
  34.                 foreach($ext['column_width']  as $k2 => $v2){
  35.                     $key   = array_search($k2, $title1_new);
  36.                     if($k == $key){
  37.                         $width = $v2;
  38.                     }
  39.                 }
  40.             }
  41.             $worksheet->getColumnDimension($k)->setWidth($width);//列宽
  42.             $styleArray = [
  43.                 'borders' => [
  44.                     'outline' => [
  45.                         'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
  46.                         'color' => ['argb' => '00000000'],
  47.                     ],
  48.                 ],
  49.                 'fill' => [
  50.                     'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_GRADIENT_LINEAR,
  51.                     'rotation' => 90,
  52.                     'startColor' => [
  53.                         'argb' => '76933C',
  54.                     ],
  55.                     'endColor' => [
  56.                         'argb' => '76933C',
  57.                     ],
  58.                 ],
  59.                 'alignment' => [
  60.                     'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
  61.                     'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER,
  62.                 ],
  63.             ];
  64.             $worksheet->getStyle($k.$startRow)->applyFromArray($styleArray);
  65.             $worksheet->setCellValue($k.$startRow, $v);
  66.             $worksheet->getRowDimension($startRow)->setRowHeight(25);
  67.         }
  68.         //画数据体
  69.         foreach($body['list'] as $k => $v){//行
  70.             $row = $startRow + $k + 1;
  71.             foreach($title1_new as $k2 => $v2){//列
  72.                 if(empty($ext['image']['column'][$v2])){
  73.                     $worksheet->setCellValue($k2.$row, $v[$v2]);
  74.                 }else{
  75.                     $drawing = new Drawing();
  76.                     //$drawing->setName($val['name']);
  77.                     //$drawing->setDescription($val['name']);
  78.                     $imgval = $v[$v2];
  79.                     $imgurl = explode('?', $imgval)[0];
  80.                     $fullfilename = $ext['image']['dir'] . basename($imgurl);
  81.                     $tmp_img_arr[] = $fullfilename;
  82.                     if(!is_file($fullfilename)){
  83.                         continue;
  84.                     }
  85.                     $drawing->setPath($fullfilename);//注意,这里的$fullfilename必须为本地图片,如果图片在网上需要先下载下来
  86.                     $drawing->setHeight(80);
  87.                     //$drawing->setWidth(50);
  88.                     $drawing->setCoordinates($ext['image']['column'][$v2] . $row);
  89.                     $drawing->setWorksheet($worksheet);
  90.                     //设置行高
  91.                     $worksheet->getRowDimension($row)->setRowHeight(60);
  92.                     unset($drawing);
  93.                 }
  94.             }
  95.             unset($body['list'][$k]);
  96.         }
  97.         //创建文件
  98.         $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
  99.         //下载表格
  100.         $filename = empty($filename) ? date('Y-m-d_H-i', time()) : $filename;
  101.         header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
  102.         header('Content-Disposition: attachment;filename="' . $filename  . '.xlsx"');
  103.         header('Cache-Control: max-age=0');//禁止缓存
  104.         $writer->save('php://output');
  105.         //释放资源防止内存溢出
  106.         $spreadsheet->disconnectWorksheets();
  107.         unset($spreadsheet, $writer);
  108.         exit();
  109.     }
复制代码
注意:$fullfilename必须为本地图片,如果你的图片是在阿里云或者七牛,需要先将这些图片下载到本地,不能实时取网上图片,否则程序运行相当慢,还可能导致图片取不到程序报错。

导出的excel效果:
[phpoffice]导出excel时带上图片,通用方法 导出,excel,图片,通用,通用方法
如果还不清楚如何使用,请到群里问群主。
我要说一句 收起回复

评论1

Discuz智能体Lv.8 发表于 2025-3-21 12:26:54 | 查看全部
在Discuz!中实现导出Excel并包含图片的功能,可以通过使用`PhpSpreadsheet`库来实现。你提供的代码已经是一个很好的起点,下面我将对其进行一些优化和解释,以确保它能够更好地适应Discuz!环境。

### 1. 引入PhpSpreadsheet库
首先,确保你已经通过Composer安装了`PhpSpreadsheet`库。如果没有安装,可以通过以下命令安装:

  1. composer require phpoffice/phpspreadsheet
复制代码


### 2. 优化代码
你提供的代码已经实现了基本的导出功能,但我们可以对其进行一些优化,使其更加健壮和易于维护。

#### 2.1 引入命名空间
确保在代码的开头引入必要的命名空间:

  1. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  2. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  3. use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
  4. use PhpOffice\PhpSpreadsheet\IOFactory;
复制代码


#### 2.2 优化`exportNew`方法
以下是优化后的`exportNew`方法:

  1. function exportNew(array $title, array $body, string $filename = '', array $ext = [], string $export_type = 'xlsx')
  2. {
  3.     if (empty($title)) {
  4.         exit('表头数据为空');
  5.     }
  6.     if (empty($body)) {
  7.         exit('导出数据为空');
  8.     }

  9.     $title1 = array_keys($title); // 字段名称
  10.     $title2 = array_values($title); // 列表头

  11.     // 生成列对应的数据字段名称
  12.     $title1_new = [];
  13.     foreach ($title1 as $k => $v) {
  14.         $letter = intToChr($k);
  15.         $title1_new[$letter] = $v;
  16.     }

  17.     // 生成excel的表头
  18.     $title2_new = [];
  19.     foreach ($title2 as $k => $v) {
  20.         $letter = intToChr($k);
  21.         $title2_new[$letter] = $v;
  22.     }

  23.     // 超大数据导出
  24.     set_time_limit(0);

  25.     // 使用模板
  26.     $spreadsheet = new Spreadsheet();
  27.     $worksheet = $spreadsheet->getActiveSheet();

  28.     // 画表头
  29.     $startRow = 1;
  30.     foreach ($title2_new as $k => $v) {
  31.         $width = 12;
  32.         if (!empty($ext) && is_array($ext)) {
  33.             foreach ($ext as $k2 => $v2) {
  34.                 $key = array_search($k2, $title1_new);
  35.                 if ($k == $key) {
  36.                     $width = $v2;
  37.                 }
  38.             }
  39.         }
  40.         $worksheet->getColumnDimension($k)->setWidth($width); // 列宽
  41.         $styleArray = [
  42.             'fill' => [
  43.                 'fillType' => Fill::FILL_SOLID,
  44.                 'startColor' => ['argb' => 'FFD9D9D9'],
  45.             ],
  46.             'alignment' => [
  47.                 'horizontal' => Alignment::HORIZONTAL_CENTER,
  48.                 'vertical' => Alignment::VERTICAL_CENTER,
  49.             ],
  50.         ];
  51.         $worksheet->getStyle($k . $startRow)->applyFromArray($styleArray);
  52.         $worksheet->setCellValue($k . $startRow, $v);
  53.         $worksheet->getRowDimension($startRow)->setRowHeight(25);
  54.     }

  55.     // 画数据体
  56.     foreach ($body as $k => $v) { // 行
  57.         $row = $startRow + $k + 1;
  58.         foreach ($title1_new as $k2 => $v2) { // 列
  59.             if (empty($ext)) {
  60.                 $worksheet->setCellValue($k2 . $row, $v);
  61.             } else {
  62.                 $drawing = new Drawing();
  63.                 $imgval = $v;
  64.                 $imgurl = explode('?', $imgval);
  65.                 $fullfilename = $ext . basename($imgurl[0]);
  66.                 $tmp_img_arr = $fullfilename;

  67.                 if (!is_file($fullfilename)) {
  68.                     continue;
  69.                 }
  70.                 $drawing->setPath($fullfilename); // 注意,这里的$fullfilename必须为本地图片
  71.                 $drawing->setHeight(80);
  72.                 $drawing->setCoordinates($k2 . $row);
  73.                 $drawing->setWorksheet($worksheet);

  74.                 // 设置行高
  75.                 $worksheet->getRowDimension($row)->setRowHeight(60);
  76.                 unset($drawing);
  77.             }
  78.         }
  79.     }

  80.     // 创建文件
  81.     $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');

  82.     // 下载表格
  83.     $filename = empty($filename) ? date('Y-m-d_H-i', time()) : $filename;
  84.     header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
  85.     header('Content-Disposition: attachment;filename="' . $filename . '.xlsx"');
  86.     header('Cache-Control: max-age=0'); // 禁止缓存
  87.     $writer->save('php://output');

  88.     // 释放资源防止内存溢出
  89.     $spreadsheet->disconnectWorksheets();
  90.     unset($spreadsheet, $writer);
  91.     exit();
  92. }
复制代码


### 3. 使用示例
假设你有一个包含图片的商品列表,你可以这样调用`exportNew`方法:

  1. $title = [
  2.     'A' => '商品名称',
  3.     'B' => '商品图片',
  4.     'C' => '商品价格',
  5. ];

  6. $body = [
  7.     ['商品1', 'http://example.com/image1.jpg', '100'],
  8.     ['商品2', 'http://example.com/image2.jpg', '200'],
  9. ];

  10. $ext = [
  11.     '商品图片' => 'B',
  12. ];

  13. exportNew($title, $body, '商品列表', $ext);
复制代码


### 4. 注意事项
- **图片路径**:确保图片路径是本地路径。如果图片存储在远程服务器(如阿里云、七牛云),需要先将图片下载到本地。
- **内存管理**:导出大量数据时,注意内存使用情况,避免内存溢出。
- **性能优化**:如果数据量非常大,可以考虑分批次导出或使用缓存机制。

### 5. 进一步学习
如果你对Discuz!的插件开发或PhpSpreadsheet的使用有更多兴趣,可以参考DZ插件网(https://www.dz-x.net)上的相关教程和文档。

希望这些信息对你有所帮助!如果有更多问题,欢迎继续提问。
-- 本回答由 人工智能 AI智能体 生成,内容仅供参考,请仔细甄别。
我要说一句 收起回复

回复

 懒得打字嘛,点击右侧快捷回复【查看最新发布】   【应用商城享更多资源】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

图文热点
关闭

站长推荐上一条 /1 下一条

最新热评 加载中...
AI智能体
投诉/建议联系

discuzaddons@vip.qq.com

未经授权禁止转载,复制和建立镜像,
如有违反,按照公告处理!!!
  • 联系QQ客服
  • 添加微信客服

联系DZ插件网微信客服|最近更新|Archiver|手机版|小黑屋|DZ插件网! ( 鄂ICP备20010621号-1 )|网站地图 知道创宇云防御

您的IP:216.73.216.212,GMT+8, 2025-6-14 19:13 , Processed in 0.360564 second(s), 75 queries , Gzip On, Redis On.

Powered by Discuz! X5.0 Licensed

© 2001-2025 Discuz! Team.

关灯 在本版发帖
扫一扫添加微信客服
QQ客服返回顶部
快速回复 返回顶部 返回列表