相信很多同学在开发过程中都多多少少的会遇到导出excel表、word文档等需求,本文讲的便是使用PHP在不使用第三方插件的情况徐爱导出csv、xls、doc的方法,下面先讲原理方法,最后将附上PHP实现。
0x01 导出csv的方法
其实这个是最简单的,csv本身就是为了方便数据的导入导出而生,并且转换为其他格式也是很容易。
csv列和列之间其实就是逗号间隔的,列和列之间是换行符间隔的所以我们在导出数据的时候只需要在列和列之间添加逗号,行和行之间添加换行符\n即可,当然,还有一种最简单的方法,就是使用fputcsv()函数,这是php原生的操作csv文件的函数,当然,也存在对应的读取文件fgetcsv(),只不过在使用的时候注意编码的转换。
0x02 导出xls的方法
这个方法其实我也是最近才发现的,其实xls列和列之间可以使用制表符\t间隔,行和行之间使用换行符\n间隔,所以在导出数据的时候只要使用fwrite()函数直接操作数据,在列和列之间添加制表符\t,行和行之间添加换行符\n即可。使用php中的implode函数可以很方便的帮助我们在他们之间添加制表符。
0x03 导出doc的方法
这个网上也有很多,其实可以将word看作html,只要添加特殊的标记,他就可以呗word读取,下面是html的模板代码:
1 2 3 4 5 6 7 8 |
<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" > <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <xml><w:WordDocument><w:View>Print</w:View></xml> </head>'; <body> </body> </html> |
只要使用上面的模板,然后在body中编写html代码,保存为doc格式就可以被word解析。
0x04 PHP代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
<?php header("Content-type: text/html; charset=utf-8"); /** * Desc 导出csv文件 * @param [string] $fileName 文件名,不包括扩展名 * @param [array] $data 一维数组或者二维数组 */ function exportCsv($fileName, $data) { header('Content-Type: application/csv'); Header("Accept-Ranges: bytes"); //Range防止断网重新请求 header('Content-Disposition: attachment; filename="' . iconv("UTF-8",'GB2312', $fileName) . '.csv"'); header('Cache-Control: max-age=0');//禁止缓存 $output = fopen("php://output", "w"); fwrite($output, chr(0xEF).chr(0xBB).chr(0xBF)); if (is_array($data)) { foreach ($data as $value) { fputcsv($output, $value); } } else { fputcsv($output, $data); } fclose($output); } /** * Desc 导出xls文件, * @param [string] $fileName 文件名,不包括扩展名 * @param [array] $data 一维数组或者二维数组 */ function exportXls($fileName, $data) { header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); Header("Accept-Ranges: bytes"); //Range防止断网重新请求 header('Content-Disposition: attachment; filename="' . iconv("utf-8",'gb2312', $fileName) . '.xls"'); header('Cache-Control: max-age=0');//禁止缓存 header("Expires:0"); $output = fopen("php://output", "w"); if (is_array($data)) { foreach ($data as $value) { fwrite($output, iconv("utf-8", "gb2312", implode("\t", $value)) . "\n"); } } else { fwrite($output, iconv("utf-8", "gb2312", implode("\t", $data)) . "\n"); } fclose($output); } /** * Desc 导出doc * @param [string] $fileName 文件名,不包括扩展名 * @param [string] $htmlBody html中Body部分 * @return [file] doc文件 */ function exportDoc($fileName, $htmlBody) { header("Cache-Control: no-store"); //所有缓存机制在整个请求/响应链中必须服从的指令 Header("Content-type: application/octet-stream"); //用于定义网络文件的类型和网页的编码,决定文件接收方将以什么形式、什么编码读取这个文件 Header("Accept-Ranges: bytes"); //Range防止断网重新请求 。 header('Content-Disposition: attachment; filename=' . iconv("utf-8",'gb2312', $fileName) . '.doc'); header('Cache-Control: max-age=0'); //禁止缓存 header("Expires:0"); //页面从浏览器高速缓存到期的时间分钟数,设定expires属性为0,将使对一页面的新的请求从服务器产生 $head = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" > <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <xml><w:WordDocument><w:View>Print</w:View></xml> </head>'; $tail = '</html>'; $data = $head . $htmlBody . $tail; $output = fopen("php://output", "w"); fwrite($output, $data); fclose($output); } ///////////////////////////////////////////////////////////////////////////////////////// $fileName = "testfile"; $data = array( array( "id", "username", "password", ), array( "1", "测试", "test" ), array( "2", "test", "test" ), ); //测试1 //exportCsv($fileName, $data); //测试2 //exportXls($fileName, $data); $body = "<body> <h1 style='text-align:center'>这是测试</h1> <p>我是内容测试</p> </body>"; //测试3 exportDoc($fileName, $body); |
上面的代码包含了三种导出方式,使用了php://output协议,运行后回直接提示下载,可以当作工具函数直接封装即可,方便实用。
0x04 补充
导出xls的方法其实并不完美,虽然可以被打开,但是在使用excel打开时时会被警告扩展名有错误,毕竟不是真正的xls,是一种投机取巧的方法。建议还是使用phpExcel插件。