之前使用了很久的PHP下载excel方法一直有个小小的bug没解决,那就是只要文件名为中文,就出现乱码。突然间觉得问题不能放着,中文的文件名还是比较好用一些,还是查找下解决方法,现在此记录下。
说到解决文件中文名乱码问题,先提下如何使用PHP下载数据并生成excel保存下来。
首先需要调用一些现有的函数,先下载个PHPEXCEL,我用的是PHPExcel_1.8.0_doc,文件夹中包含以下几个文件:
PHP下载数据文件现命名为test.php,需要调用PHPEXCEL中文件,require_once '../../PHPExcel_1.8.0_doc/Classes/PHPExcel.php';
其次是excel的基本设置:
$objPHPExcel=new PHPExcel();
$objPHPExcel->getProperties()->setCreator('sf')
->setLastModifiedBy('sf')
->setTitle('Office 2007 XLSX Document')
->setSubject('Office 2007 XLSX Document')
->setDescription('Document for Office 2007 XLSX, generated using PHP classes.')
->setKeywords('office 2007 openxml php')
->setCategory('Result file');
第一行单元格一般为列名,必要时候可以设置单元格格式:
//给单元格设计样式和颜色
$objPHPExcel->getActiveSheet()->getStyle('A1:P1')->applyFromArray(
array(
'font' =>array(
'bold' =>true,
),
'borders'=>array(
'allborders'=>array(
'style'=>PHPExcel_Style_Border::BORDER_THIN
)
),
'fill'=>array(
'type'=>PHPExcel_Style_Fill::FILL_SOLID,
'rotation'=>90,
'startcolor'=>array(
'rgb'=>'00cd66'
),
'endcolor'=>array(
'rgb'=>'00cd66'
)
)
)
);
填充第一行单元格内容:
$objPHPExcel->setActiveSheetIndex(0)
->setCellValue('A1','测试1')
->setCellValue('B1','测试2')
->setCellValue('C1','测试3')
->setCellValue('D1','测试4')
->setCellValue('E1','测试5')
->setCellValue('F1','测试6')
->setCellValue('G1','测试7')
->setCellValue('H1','测试8')
->setCellValue('I1','测试9')
->setCellValue('J1','测试10')
->setCellValue('K1','测试11')
->setCellValue('L1','测试12')
->setCellValue('M1','测试13')
->setCellValue('N1','测试14')
->setCellValue('O1','测试15')
->setCellValue('P1','测试16');
这里开始填充之后的数据,但数据的来源一般是来自数据库,涉及到sql语句中的select语句。而后台实现和前台界面联系,要实现不是每次都下载所有数据,而是筛选数据后下载筛选后的数据,我目前的方法是前台保存搜索的sql语句,并通过跳转链接传递变量,将整个sql语句当作一个string变量传递。
因此,这里执行sql语句,$query=@mysql_query($_GET['sql'],$conn) or die(MySQL_error());$numrows=@mysql_num_rows($query);
判断下执行语句是否为空,为空不下载;不为空,while执行while($data=@mysql_fetch_array($query)){}将结果一条一条插入到excel表格中,如果大家有更好的方法,可以批量插入的,希望共享下方法。
while($data=@mysql_fetch_array($query)){
$count+=1;//先指向第二行单元格
$l1="A"."$count";
$l2="B"."$count";
$l3="C"."$count";
$l4="D"."$count";
$l5="E"."$count";
$l6="F"."$count";
$l7="G"."$count";
$l8="H"."$count";
$l9="I"."$count";
$l10="J"."$count";
$l11="K"."$count";
$l12="L"."$count";
$l13="M"."$count";
$l14="N"."$count";
$l15="O"."$count";
$l16="P"."$count";
$objPHPExcel->setActiveSheetIndex(0)
->setCellValue($l1,$data['test1'])
->setCellValue($l2,$data['test2'])
->setCellValue($l3,$data['test3'])
->setCellValue($l4,$data['test4'])
->setCellValue($l5,$data['test5'])
->setCellValue($l6,$data['test6'])
->setCellValue($l7,$data['test7'])
->setCellValue($l8,$data['test8'])
->setCellValue($l9,$data['test9'])
->setCellValue($l10,$data['test10'])
->setCellValue($l11,$data['test11'])
->setCellValue($l12,$data['test12'])
->setCellValue($l13,$data['test13'])
->setCellValue($l14,$data['test14'])
->setCellValue($l15,$data['test15'])
->setCellValue($l16,$data['test16']);
}
开始设置sheet单元格名称和sheet单元格所在位置,以及文件名名称:
$objPHPExcel->getActiveSheet()->setTitle('测试测试测试测试测试测试');//sheet单元格名称
$objPHPExcel->setActiveSheetIndex(0);//sheet单元格所在位置,索引
$filename='测试表测试表测试表';//excel文件名名称
当然这里直接下载不做任何设置,结果就会出现开头出现的文件,下载的文件名是乱码,因此,这里必须添加一句:
$filename=urlencode($filename);//防止文件名为中文时出现乱码
现在可以进行下面的操作了:
header('Content-Disposition: attachment;filename="'.$filename.'.xls"');
header('Cache-Control: max-age=0');
$objWriter=PHPExcel_IOFactory::createWriter($objPHPExcel,'Excel5');
exit;