设为首页收藏本站

EPS数据狗论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1431|回复: 1

[其他] 导出数据到Excel的实用方案

[复制链接]

32

主题

313

金钱

473

积分

入门用户

发表于 2019-4-28 15:12:02 | 显示全部楼层 |阅读模式

实际工作场景中,经常需要将系统中数据导出为Excel,便于产品和运营查阅和二次处理。本文详细介绍了使用PHP导出数据的方法。

PHP操作Excel主要有两个第三方库,一个是 PHPExcel ,另外一个是 PhpSpreadsheet 。其中PhpSpreadsheet是PHPExcel的升级版本。

PHPExcel本身支持超链接、样式设置(字体、颜色、边框线、对齐等)、行高列宽设置、表格冻结、公式、合并单元格、多表格等特性。从官方文档得知,PHPExcel支持PHP5.2版本,代码质量和性能会低于PhpSpreadsheet。另外PHPExcel从2015年便不再维护,因此很难从社区增加新特性和处理历史缺陷。PHPExcel支持xls和xlsx两种格式,xls是Microsoft Excel 2003以下版本支持的文件,xlsx是Microsoft Excel 2007以后开始的。

PhpSpreadsheet是下一代的PHPExcel,支持PHP5.6及以上,可以处理Microsoft Excel和LibreOffice Calc。PhpSpreadsheet作为下一代的PHPExcel,目前得到社区持续维护。

基于本身业务特点,以及疑难问题的快速处理,最终选择了PHPExcel作为导出的基础库,并且采用xls文件格式。PHPExcel库因为历史久远,积累了很多其他用户踩过的坑,也便于我们处理类似疑难问题。

下文所述的方法是将内容导出为xls文件格式。

处理中-内容的处理
处理多sheet
核心方法:$obj_phpexcel->createSheet(​$i);
  1. $obj_phpexcel = new PHPExcel();
  2. $sheet_datas;//实际数据
  3. $sheet_name = 'test';
  4. foreach($sheet_datas as $i => $sheet_data) {
  5.         $obj_phpexcel->createSheet($i);
  6.         $obj_phpexcel->setActiveSheetIndex($sheet_index);
  7.         $obj_phpexcel->getActiveSheet()->setTitle($sheet_name);
  8. }
复制代码


处理样式
核心方法: $obj_phpexcel->getActiveSheet()->getStyle(‘A1’)->applyFromArray($style_array);

getStyle的参数为实际坐标,比如A1,代表A列的第1行的单元格。applyFromArray的参数为样式配置。
  1. //样式配置
  2. $style_array = array(
  3.     'alignment' => array(
  4.         'horizontal' =>
  5.             PHPExcel_Style_Alignment::HORIZONTAL_GENERAL           = 'general'
  6.             PHPExcel_Style_Alignment::HORIZONTAL_LEFT              = 'left'
  7.             PHPExcel_Style_Alignment::HORIZONTAL_RIGHT             = 'right'
  8.             PHPExcel_Style_Alignment::HORIZONTAL_CENTER            = 'center'
  9.             PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS = 'centerContinuous'
  10.             PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY           = 'justify'
  11.         'vertical' =>
  12.             PHPExcel_Style_Alignment::VERTICAL_BOTTOM  = 'bottom'
  13.             PHPExcel_Style_Alignment::VERTICAL_TOP     = 'top'
  14.             PHPExcel_Style_Alignment::VERTICAL_CENTER  = 'center'
  15.             PHPExcel_Style_Alignment::VERTICAL_JUSTIFY = 'justify'
  16.         'rotation' => (int)
  17.         'wrap' => (boolean)
  18.         'shrinkToFit' => (boolean)
  19.         'indent' => (int)
  20.     )
  21.     'borders' => array(
  22.         'allborders' => array(
  23.             'style' =>
  24.                 PHPExcel_Style_Border::BORDER_NONE               = 'none';
  25.                 PHPExcel_Style_Border::BORDER_DASHDOT            = 'dashDot';
  26.                 PHPExcel_Style_Border::BORDER_DASHDOTDOT         = 'dashDotDot';
  27.                 PHPExcel_Style_Border::BORDER_DASHED             = 'dashed';
  28.                 PHPExcel_Style_Border::BORDER_DOTTED             = 'dotted';
  29.                 PHPExcel_Style_Border::BORDER_DOUBLE             = 'double';
  30.                 PHPExcel_Style_Border::BORDER_HAIR               = 'hair';
  31.                 PHPExcel_Style_Border::BORDER_MEDIUM             = 'medium';
  32.                 PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT      = 'mediumDashDot';
  33.                 PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT   = 'mediumDashDotDot';
  34.                 PHPExcel_Style_Border::BORDER_MEDIUMDASHED       = 'mediumDashed';
  35.                 PHPExcel_Style_Border::BORDER_SLANTDASHDOT       = 'slantDashDot';
  36.                 PHPExcel_Style_Border::BORDER_THICK              = 'thick';
  37.                 PHPExcel_Style_Border::BORDER_THIN               = 'thin';
  38.             'color' => array(
  39.                 'rgb' =>
  40.                     PHPExcel_Style_Color::COLOR_BLACK            = 'FF000000';
  41.                     PHPExcel_Style_Color::COLOR_WHITE            = 'FFFFFFFF';
  42.                     PHPExcel_Style_Color::COLOR_RED              = 'FFFF0000';
  43.                     PHPExcel_Style_Color::COLOR_DARKRED          = 'FF800000';
  44.                     PHPExcel_Style_Color::COLOR_BLUE             = 'FF0000FF';
  45.                     PHPExcel_Style_Color::COLOR_DARKBLUE         = 'FF000080';
  46.                     PHPExcel_Style_Color::COLOR_GREEN            = 'FF00FF00';
  47.                     PHPExcel_Style_Color::COLOR_DARKGREEN        = 'FF008000';
  48.                     PHPExcel_Style_Color::COLOR_YELLOW           = 'FFFFFF00';
  49.                     PHPExcel_Style_Color::COLOR_DARKYELLOW       = 'FF808000';
  50.             )

  51.         )
  52.         'left' => // See 'allborders'
  53.         'top' => // See 'allborders'
  54.         'right' => // See 'allborders'
  55.         'bottom' => // See 'allborders'
  56.         'diagonal' =>
  57.         'diagonaldirection' =>
  58.     )
  59.     'fill' => array(
  60.         'type' =>
  61.             PHPExcel_Style_Fill::FILL_NONE                         = 'none';
  62.             PHPExcel_Style_Fill::FILL_SOLID                        = 'solid';
  63.             PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR              = 'linear';
  64.             PHPExcel_Style_Fill::FILL_GRADIENT_PATH                = 'path';
  65.             PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN             = 'darkDown';
  66.             PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY             = 'darkGray';
  67.             PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID             = 'darkGrid';
  68.             PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL       = 'darkHorizontal';
  69.             PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS          = 'darkTrellis';
  70.             PHPExcel_Style_Fill::FILL_PATTERN_DARKUP               = 'darkUp';
  71.             PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL         = 'darkVertical';
  72.             PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625             = 'gray0625';
  73.             PHPExcel_Style_Fill::FILL_PATTERN_GRAY125              = 'gray125';
  74.             PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN            = 'lightDown';
  75.             PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY            = 'lightGray';
  76.             PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID            = 'lightGrid';
  77.             PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL      = 'lightHorizontal';
  78.             PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS         = 'lightTrellis';
  79.             PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP              = 'lightUp';
  80.             PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL        = 'lightVertical';
  81.             PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY           = 'mediumGray';
  82.         'rotation' => (double)
  83.         'startcolor' => // See 'borders' => 'allborders' => 'color'
  84.         'endcolor' => // See 'borders' => 'allborders' => 'color'
  85.         'color' => // See 'borders' => 'allborders' => 'color'
  86.     )
  87.     'font' => array(
  88.         'name' =>
  89.             'Arial'
  90.             'Calibri'
  91.             // etc.
  92.         'bold' => (boolean)
  93.         'italic' => (boolean)
  94.         'superScript' => (boolean)
  95.         'subScript' => (boolean)
  96.         'underline' => (boolean)
  97.         'strike' => (boolean)
  98.         'size' => (float)
  99.         'color' => // See 'borders' => 'allborders' => 'color'
  100.     )
  101.     'numberformat' =>
  102.     'protection' =>
  103. )
复制代码


写入数据
核心方法:$obj_phpexcel->getActiveSheet()->setCellValueExplicit(‘A1’, $value, $dtype);

dtype区分不同的数据类型,定义见PHPExcel\Cell\DataType.php
  1. /* Data types */
  2. const TYPE_STRING2  = 'str';
  3. const TYPE_STRING   = 's';
  4. const TYPE_FORMULA  = 'f';
  5. const TYPE_NUMERIC  = 'n';
  6. const TYPE_BOOL     = 'b';
  7. const TYPE_NULL     = 'null';
  8. const TYPE_INLINE   = 'inlineStr';
  9. const TYPE_ERROR    = 'e';
复制代码


处理超链接
核心方法:$obj_phpexcel->getActiveSheet()->getCell(‘A1’)->getHyperlink()->setUrl($URL);
处理公式
核心方法:$obj_phpexcel->getActiveSheet()->setCellValue(‘A1’, ‘=SUM(A10:E9)’);
合并单元格
核心方法:$obj_phpexcel->getActiveSheet()->mergeCells(‘A1:C1’);
列宽和行高
  1. //列宽
  2. $obj_phpexcel->getActiveSheet()->getColumnDimension($column_label)->setWidth($value);
  3. //行高
  4. $obj_phpexcel->getActiveSheet()->getRowDimension($key)->setRowHeight($value);
复制代码

表格冻结
核心方法:$obj_phpexcel->getActiveSheet()->freezePane(‘D2’);

其他问题
实际值、像素值隐射
PHPExcel没办法将像素值,转化为Microsoft Excel实际的宽度和高度值。如果直接将像素值设置为Excel的实际值,会导致内容存在差异。经过测试得知,Excel实际值和像素值之间满足线性关系。知道问题原因,处理起来便很简单。
  1. private function _get_excel_real_width($value) {
  2.         return $value/7;
  3. }
复制代码


横坐标处理
Excel的横坐标为A、B….、AA、AB类型,需要将PHP数组下标转化为Excel的横坐标。
  1. private function _get_sheet_col_label($index) {

  2.         if (isset($this->_col_label_map[$index])) {
  3.                 return $this->_col_label_map[$index];
  4.         }
  5.         $abc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  6.         for ($i=0; $i < 600; $i++) { //最高支持600列
  7.                 $a = (int)($i / 26);
  8.                 $b = $i % 26;
  9.                 $column_label = '';
  10.                 if ($a == 0) {
  11.                         $column_label = $column_label . substr($abc, $b, 1);
  12.                 } else {
  13.                         $a = $a -1;
  14.                         $column_label = substr($abc, $a, 1) . substr($abc, $b, 1);
  15.                 }
  16.                 $this->_col_label_map[($i)] = $column_label;
  17.         }
  18.         return $this->_col_label_map[$index];
  19. }
复制代码


默认的样式处理
Excel本身的表格框线无法通过PHPExcel设置,需要trick处理。另外Excel的样式属性与css样式属性也会有差异,需要注意下。
  1. //设置Excel默认框线
  2. $style_array = array(
  3.       'borders' => array(
  4.           'allborders' => array(
  5.                 'style' => PHPExcel_Style_Border::BORDER_THIN,
  6.                             'color' => array('rgb' => 'DDDDDD')
  7.           )
  8.       )
  9.   );
复制代码

351

主题

2万

金钱

3万

积分

版主

QQ
发表于 2019-5-3 08:58:35 | 显示全部楼层
谢谢分享
dog rich, don't forget
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

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

客服中心
关闭
在线时间:
周一~周五
8:30-17:30
QQ群:
653541906
联系电话:
010-85786021-8017
在线咨询
客服中心

意见反馈|网站地图|手机版|小黑屋|EPS数据狗论坛 ( 京ICP备09019565号-3 )   

Powered by BFIT! X3.4

© 2008-2028 BFIT Inc.

快速回复 返回顶部 返回列表