使用phpexcel操作excel
使用这个组件最让我郁闷的是,它对sheet的名称为中文的不进行处理,暂时还没仔细去查原因。
对excel的操作,无非有两种:读与写,分别对应的为phpexcel中的writer与reader类。
phpexcel中的方法很多,若不是特殊的需求,常用的一些已经够用了。下面直接看例子,思路应该是比较清晰的:
1、写excel:
1: <meta http-equiv="content-type" content="text/html; charset=utf-8">
2: <title>对excel的测试实例_1</title>
3: <?php
4:
5: error_reporting(E_ALL);
6:
7: //设置时区
8: date_default_timezone_set('Asia/Shanghai');
9:
10: require_once 'Classes/PHPExcel.php';
11:
12: echo '当前时间:'.date('Y:m:d H:i:s');
13:
14: //创建excel操作对象
15: $objPHPExcel = new PHPExcel();
16:
17: $objPHPExcel->getProperties()->setCreator("Meteoric_cry")
18: ->setLastModifiedBy("Meteoric002")
19: ->setTitle("Php_excel_demo1")
20: ->setSubject("主题1")
21: ->setDescription("随便一个描述了")
22: ->setKeywords("关键字 用空格分开")
23: ->setCategory("分类 ");
24:
25: //激活第一个选项, 然后填充数据
26: $objPHPExcel->setActiveSheetIndex(0)
27: ->setCellValue('A1', 'Hello')
28: ->setCellValue('B2', 'world!')
29: ->setCellValue('C1', 'Hello')
30: ->setCellValue('D2', 'world!');
31:
32: $objPHPExcel->setActiveSheetIndex(0)
33: ->setCellValue('A4', 'Miscellaneous glyphs')
34: ->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç');
35:
36: //对第一个选项进行重命名
37: $objPHPExcel->getActiveSheet()->setTitle('重新命令');
38:
39:
40: $objPHPExcel->setActiveSheetIndex(0);
41:
42: //写操作
43: $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
44: $objWriter->save(str_replace('.php', '.xlsx', __FILE__));
45:
46: echo "<br/>消耗的内存为:".memory_get_peak_usage(true) / 1024 / 1024;
47: echo '<div>文件名:'.__FILE__.'</div>';
48: echo '<div>php编译的行数:'.__LINE__.'</div>';
49: echo '<div>php的类名:'.__CLASS__.'</div>';
50: ?>
运行后,会发现在当前目录下生成一个与php名称对应的excel文件
上面主要需要注意的是:createWriter方法,它的实现方法是:
1: /**
2: * Create PHPExcel_Writer_IWriter
3: *
4: * @static
5: * @access public
6: * @param PHPExcel $phpExcel
7: * @param string $writerType Example: Excel2007
8: * @return PHPExcel_Writer_IWriter
9: * @throws Exception
10: */
11: public static function createWriter(PHPExcel $phpExcel, $writerType = '') {
12: // Search type
13: $searchType = 'IWriter';
14:
15: // Include class
16: foreach (self::$_searchLocations as $searchLocation) {
17: if ($searchLocation['type'] == $searchType) {
18: $className = str_replace('{0}', $writerType, $searchLocation['class']);
19: $classFile = str_replace('{0}', $writerType, $searchLocation['path']);
20:
21: $instance = new $className($phpExcel);
22: if (!is_null($instance)) {
23: return $instance;
24: }
25: }
26: }
27:
28: // Nothing found...
29: throw new Exception("No $searchType found for type $writerType");
30: } // function createWriter()
而对应的excel文件类型有如下这些:
1: /**
2: * Autoresolve classes
3: *
4: * @var array
5: * @access private
6: * @static
7: */
8: private static $_autoResolveClasses = array(
9: 'Excel2007',
10: 'Excel5',
11: 'Excel2003XML',
12: 'OOCalc',
13: 'SYLK',
14: 'Gnumeric',
15: 'CSV',
16: );
同样的,对于读操作也是如此。只不过可能省略设定类型。
2、读Excel文件:
读取excel有两种方式:
1: //first method
2: $objReader = PHPExcel_IOFactory::createReader("Excel2007");
3: $objPHPExcel = $objReader->load($fileName);
4:
5: //second method
6: $objPHPExcel = PHPExcel_IOFactory::load($fileName);
不过使用第一种,编辑器里就没有提示方法显示了,所以我选的第二种,反正它会根据后缀名判定excel的类型。
读取excel文件,关键的有如下几点:
1、需要获取所有的记录行数
可使用 $objPHPExcel->getActiveSheet()->getRowDimensions()可获取到所有行记录的记录集合(一个数组array)
2、需要获取最大的列数
可使用$objPHPExcel->getActiveSheet()->getColumnDimensions();方法获取,返回的也是一个数组集合
3、如何读取某一行中指定列的内容
可使用$objPHPExcel->getActiveSheet()->getCellByColumnAndRow($cellIndex, $rowIndex)->getValue(),指定列数(注意列在前面,行在后面),再调用它的getValue()就可以得到内容
得到两人上数组,然后循环获取每一行中各列的数据,再对数据根据需求进行处理就好了。完整的示例代码:
1: <meta http-equiv="content-type" content="text/htm; charset=utf-8">
2: <title>excel转化为sql脚本</title>
3: <?php
4: error_reporting(E_ALL);
5: date_default_timezone_set("Asia/Shanghai");
6:
7: $startTime = time();
8:
9: echo "<div>现在时间:".date("Y:m:d H:i:s")."</div>";
10:
11: require_once '../Classes/PHPExcel/IOFactory.php';
12:
13: $fileName = dirname(__FILE__)."/task_list.xlsx";
14:
15: if (!file_exists($fileName)) {
16: exit("文件".$fileName."不存在");
17: }
18:
19: //$objReader = PHPExcel_IOFactory::createReader("Excel2007");
20: //$objPHPExcel = $objReader->load($fileName);
21: $objPHPExcel = PHPExcel_IOFactory::load($fileName);
22: $sheetCount = $objPHPExcel->getSheetCount();
23:
24: $sheetSelected = 0;
25: $objPHPExcel->setActiveSheetIndex($sheetSelected);
26:
27: $rowArray = $objPHPExcel->getActiveSheet()->getRowDimensions();
28: $cellArray = $objPHPExcel->getActiveSheet()->getColumnDimensions();
29: $rowCount = count($rowArray);
30: $cellCount = count($cellArray);
31:
32: echo "<div>Sheet Count : ".$sheetCount." 行数: ".$rowCount." 列数:".$cellCount."</div>";
33:
34: $rowIndex = 0;
35: $cellIndex = 0;
36: $rowData = NULL;
37:
38: $dataArr = array();
39:
40: while ($rowIndex < $rowCount) {
41: $cellIndex = 0;
42:
43: $rowData = $objPHPExcel->getActiveSheet();
44:
45: array_push($dataArr, "<div style='margin-top:20px;'>");
46: while ($cellIndex < $cellCount) {
47: array_push($dataArr, "<div>".$rowData->getCellByColumnAndRow($cellIndex, $rowIndex)->getValue()."</div>");
48: $cellIndex++;
49: }
50: array_push($dataArr, "</div>");
51:
52: $rowIndex++;
53: }
54:
55: echo "<br/>消耗的内存为:".(memory_get_peak_usage(true) / 1024 / 1024)."M";
56:
57: $endTime = time();
58:
59: echo "<div>解析完后,当前的时间为:".date("Y-m-d H:i:s")." 总共消耗的时间为:".(($endTime - $startTime))."秒</div>";
60:
61: echo implode("", $dataArr);
62:
63: $dataArr = NULL;
64: ?>
对于相对路径来讲,可以不使用魔术变量__FILE__,思路在那里,只要不写成死循环,实现了功能就达到了预期的目的。其实上面的代码是比较消耗内存的,因为内存中把存放两次数据:一个是列记录数组,一个是行记录数组,还有一个是每一行名列的数据。如果先创建一个文件,然后将数据逐行写入文件中,会减少一些对内存的开销。
预览一下最终的效果: