## 1 简介
### 1.1 导出
在实际的工作项目中,经常需要将一些重要的数据库中存的数据导出成Excel,比如导出考勤报表,导出财务报表,导出业绩报表,导出销售报表等。CleverCode以前使用了两年的PHPExcel来制作Excel导出数据,但发现用PHPExcel生成Excel实在是太麻烦了,特别是控制单元格的颜色,合并单元格,给单元格设置长度等。这些设计一个Excel通常会需要花费一天的时间。后来CleverCode发现了一个简便的方法PHP导出xml格式的Excel,以前需要一天的工作量,现在半小时就搞定了,实在是事半功倍!
### 1.2 导入
同时有的项目也需要,将一些Excel数据导入到数据库中。比如银行给的银行流水,销售报表导入的数据库中。这个通常的做法都是使用PHPExcel。
虽然读取xml格式的Excel可以使用Xml parser, SimpleXML, XMLReader, DOMDocument等方式,但是CleverCode尝试过使用这些方式,发现太复杂,太费劲,没有PHPExcel好使。
所以当需要读取Excel的时候(包括xml格式的),CleverCode推荐使用PHPExcel库。
## 2 需求
某个集团需要各个地区的负责人将其负责的城市站的订单和销售额导入到数据库。
1)网站提供一个导入的销售报表模板。
2)每个负责人只能上传与下载各自负责城市的数据(权限检查)。
3)只用上传生成当年,当日的拥有的所有季度。比如今天是2015-05-26。那么只有生成2015一季度,与二季度。
如果是2015-12-01。则需要生成2015一,二,三,四季度。
4)显示本季度以前季度的数据。
5)本季度的数据默认全是0。
6)只能修改本季度的数据。
## 3 程序设计源码下载
[http://download.csdn.net/detail/clevercode/8750869](http://download.csdn.net/detail/clevercode/8750869)
## 4 设计网站页面
### 4.1 显示
![](https://box.kancloud.cn/2016-04-07_5705f4fe8343f.jpg)
### 4.2 display.php代码
~~~
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk" />
<title>PHP导入与导出xml格式的Excel</title>
<style type="text/css">
body{ font-size:14px;}
input{ vertical-align:middle; margin:0; padding:0}
.file-box{ position:relative;width:340px}
.txt{ height:22px; border:1px solid #cdcdcd; width:180px;}
.btn{ background-color:#FFF; border:1px solid #CDCDCD;height:24px; width:70px;}
.file{ position:absolute; top:0; right:80px; height:24px; filter:alpha(opacity:0);
opacity: 0;width:260px }
</style>
</head>
<body>
<div class="file-box">
<form action="" method="post" enctype="multipart/form-data">
<input type='text' name='textfield' id='textfield' class='txt' />
<input type='button' class='btn' value='浏览...' />
<input type="file" name="fileField" class="file" id="fileField" size="28"
onchange="document.getElementById('textfield').value=this.value" />
<input type="submit" name="submit" class="btn" value="上传" />
</form>
<a href="export.php">下载销售报表模板</a>
</div>
</body>
</html>
~~~
## 5 PHP导出xml格式的Excel(导出销售报表模板)
1)新建一个【销售报表.xlsx】。设计如下。
![](https://box.kancloud.cn/2016-04-07_5705f4fe99c4c.jpg)
2)将【销售报表.xlsx】文件另存为【销售报表.xml】
![](https://box.kancloud.cn/2016-04-07_5705f4febfed1.jpg)
![](https://box.kancloud.cn/2016-04-07_5705f4ff0086c.jpg)
3)打开【销售报表.xml】可以看到xml格式的数据。
4)找到table信息。删除掉ss:ExpandedColumnCount="5" ss:ExpandedRowCount="6"。这个限制死了表格的长度和宽度,所以必须去掉。
<Table ss:ExpandedColumnCount="5" ss:ExpandedRowCount="6" x:FullColumns="1"
x:FullRows="1" ss:StyleID="s23" ss:DefaultColumnWidth="54"
ss:DefaultRowHeight="18.75">
改成
<Table x:FullColumns="1"
x:FullRows="1" ss:StyleID="s23" ss:DefaultColumnWidth="54"
ss:DefaultRowHeight="18.75">
![](https://box.kancloud.cn/2016-04-07_5705f4ff31258.jpg)
5 PHP导出Excel业务逻辑代码(Excel.php)
~~~
<?php
/**
* Excel.php
*
* Excel操作
*
* Copyright (c) 2015 http://blog.csdn.net/CleverCode
*
* modification history:
* --------------------
* 2015/5/14, by CleverCode, Create
*
*/
class Excel{
/**
* 导出excel
*
* @param int $userid 用户编号
* @return string $xmlStr
*/
public static function export($userid){
// 根据不同用户的权限,获取不同的数据
$data = self::getExportData($personid);
// 获取字符串,如果excel的列是固定的可以通过Smarty方式获取
// 但是如果excel的列需要通过动态生成,则可以通过php组合字符串。
// $xmlStr = self::getXmlStrBySmarty($data);
// 这个需要根据当前日期动态的生成有几个季度
$xmlStr = self::getXmlStrByPHP($data);
return $xmlStr;
}
/**
* 生成excel数据
*
* @param int $userid 用户编号
* @return array 结果数据
*/
public static function getExportData($userid){
if (!is_int($userid)) {
return array();
}
$infoBJ = array(
'city' => '北京',
'order_1' => 100,
'money_1' => 10000,
'order_2' => 200,
'money_2' => 40000
);
$infoTJ = array(
'city' => '天津',
'order_1' => 50,
'money_1' => 1000,
'order_2' => 100,
'money_2' => 2000
);
$infoGZ = array(
'city' => '广州',
'order_1' => 50,
'money_1' => 1000,
'order_2' => 100,
'money_2' => 2000
);
// 根据不同用户的权限,获取不同的数据
if (is_admin($userid)) {
$data[] = $infoBJ;
$data[] = $infoTJ;
$data[] = $infoGZ;
} else {
$data[] = $infoBJ;
}
return $data;
}
/**
* 通过Smarty方式获取xml字符串
*
* @param array $data 结果集
* @return string $xmlStr
*/
public static function getXmlStrBySmarty($data){
require_once 'Smarty.class.php';
$smarty = new Smarty();
$tpl = 'file/export.tpl';
$smarty->assign('list', $data);
// capture the output
// 捕获输出
$xml = $smarty->fetch($tpl);
return $xml;
}
/**
* 通过PHP组合字符串方式获取xml字符串(可以动态扩展列)
*
* @param array $data 结果集
* @return string $xmlStr
*/
public static function getXmlStrByPHP($data){
$xml = '
<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
............
</Style>
</Styles>
<Worksheet ss:Name="Sheet1">
<Table x:FullColumns="1"
x:FullRows="1" ss:StyleID="s16" ss:DefaultColumnWidth="54"
ss:DefaultRowHeight="18.75">
';
//可以根据季度的多少动态扩展列,这里不做说明,请自行尝试。
$xml. = '
<Row ss:AutoFitHeight="0">
<Cell ss:MergeDown="1" ss:StyleID="m42513364"><Data ss:Type="String">城市</Data></Cell>
<Cell ss:MergeAcross="1" ss:StyleID="s25"><Data ss:Type="String">2015一季度</Data></Cell>
<Cell ss:MergeAcross="1" ss:StyleID="m42513344"><Data ss:Type="String">2015二季度</Data></Cell>
</Row>
<Row ss:AutoFitHeight="0">
<Cell ss:Index="2" ss:StyleID="s17"><Data ss:Type="String">订单</Data></Cell>
<Cell ss:StyleID="s17"><Data ss:Type="String">销售额</Data></Cell>
<Cell ss:StyleID="s17"><Data ss:Type="String">订单</Data></Cell>
<Cell ss:StyleID="s17"><Data ss:Type="String">销售额</Data></Cell>
</Row>
';
// 输出数据
foreach ( $data as $row ) {
$xml .= '
<Row ss:AutoFitHeight="0">
<Cell ss:StyleID="s18"><Data ss:Type="String">' . $row['city'] . '</Data></Cell>
<Cell ss:StyleID="s19"><Data ss:Type="Number">' . $row['order_1'] . '</Data></Cell>
<Cell ss:StyleID="s19"><Data ss:Type="Number">' . $row['money_1'] . '</Data></Cell>
<Cell ss:StyleID="s19"><Data ss:Type="Number">' . $row['order_2'] . '</Data></Cell>
<Cell ss:StyleID="s19"><Data ss:Type="Number">' . $row['money_2'] . '</Data></Cell>
</Row>
';
}
$xml .= '
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
...........
</Workbook>
';
return $xml;
}
}
~~~
6 PHP导出Excel客户端代码(export.php)
~~~
<?php
/**
* export.php
*
* 导出excel
*
* Copyright (c) 2015 http://blog.csdn.net/CleverCode
*
* modification history:
* --------------------
* 2015/5/14, by CleverCode, Create
*
*/
// Excel类
include_once ('Excel.php');
/*
* 客户端类
* 让客户端和业务逻辑尽可能的分离,降低客户端和业务逻辑算法的耦合,
* 使业务逻辑的算法更具有可移植性
*/
class Client{
public function main(){
// 获取xml格式字符串
$xmlStr = Excel::export(1);
// 头部
$filename = '销售报表模板';
header("Content-Type: application/vnd.ms-excel; charset=UTF-8");
header("Content-Disposition: inline; filename=\"$filename.xls\"");
header("Content-Transfer-Encoding: binary");
header("Pragma: public");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
// 输出字符串
echo $xmlStr;
exit();
}
}
/**
* 程序入口
*/
function start(){
$client = new Client();
$client->main();
}
start();
?>
~~~
## 6 PHP导入xml格式的Excel
1)下载销售模板后,填写其中的数据,然后点击页面中的上传按钮,上传Excel数据。
![](https://box.kancloud.cn/2016-04-07_5705f4ff8c56e.jpg)
2) PHP导入的Excel业务逻辑代码(Excel.php)。这里使用了PHPExcel库。
~~~
<?php
/**
* Excel.php
*
* Excel操作
*
* Copyright (c) 2015 http://blog.csdn.net/CleverCode
*
* modification history:
* --------------------
* 2015/5/14, by CleverCode, Create
*
*/
class Excel{
/*
* 读取Excel格式的数据(可以读取xml格式数据)
*
* @param string $filename excel文件
* @param string $startRow 开始行
* @param string $endRow 结束行
* @param string $startColumn 开始列
* @param string $endColumn 结束列
* @return array excel结果集数据
*/
public static function read($filename, $startRow = 1, $endRow = null, $startColumn = 0, $endColumn = null){
$excelData = array();
if (!file_exists($filename)) {
return $excelData;
}
require_once 'PHPExcel/PHPExcel.php';
require_once 'PHPExcel/PHPExcel/IOFactory.php';
// 加载excel文件
$objPHPExcel = PHPExcel_IOFactory::load($filename);
// 获取焦点Sheet
$objWorksheet = $objPHPExcel->getActiveSheet();
// 获取总行
$totalRows = $objWorksheet->getHighestRow(); // 获取总行数
// 获取总列
$highestColumn = $objWorksheet->getHighestColumn();
$totalColumns = PHPExcel_Cell::columnIndexFromString($highestColumn);
// 开始行
if (!is_int($startRow) || $startRow < 1) {
$startRow = 1;
}
// 结束行
if ($endRow == null || !is_int($endRow) || $endRow > $totalRows) {
$endRow = $totalRows;
}
// 开始列
if (!is_int($startColumn) || $startColumn < 0) {
$startColumn = 0;
}
// 结束列
if ($endColumn == null || !is_int($endColumn) || $endColumn > $totalColumns) {
$endColumn = $totalColumns;
}
// 读取数据
for($rowNum = $startRow; $rowNum <= $endRow; $rowNum++) {
for($colNum = $startColumn; $colNum < $endColumn; $colNum++) {
$item = $objWorksheet->getCellByColumnAndRow($colNum, $rowNum);
$exValue = trim($item->getValue());
$excelData[$rowNum][$colNum] = $exValue;
}
}
return $excelData;
}
}
~~~
3) PHP导入的Excel客户端代码(import.php)
~~~
<?php
/**
* import.php
*
* 导入excel
*
* Copyright (c) 2015 http://blog.csdn.net/CleverCode
*
* modification history:
* --------------------
* 2015/5/14, by CleverCode, Create
*
*/
// Excel类
include_once ('Excel.php');
/*
* 客户端类
* 让客户端和业务逻辑尽可能的分离,降低客户端和业务逻辑算法的耦合,
* 使业务逻辑的算法更具有可移植性
*/
class Client{
public function main(){
if (!$_FILES['file']) {
exit();
}
// 从第3行开始读取Excel数据
$datas = Excel::read($_FILES['file']['tmp_name'], 3);
// 将$datas保存到数据库
// ....
}
}
/**
* 程序入口
*/
function start(){
$client = new Client();
$client->main();
}
start();
?>
~~~
**版权声明:**
1)原创作品,出自"CleverCode的博客",转载时请务必注明以下原创地址,否则追究版权法律责任。
2)原创地址:[http://blog.csdn.net/clevercode/article/details/46226461](http://blog.csdn.net/clevercode/article/details/46226461)(转载务必注明该地址)。
3)分类地址(PHP程序员技术精粹):[http://blog.csdn.net/clevercode/article/category/3169943](http://blog.csdn.net/clevercode/article/category/3169943)(博客持续增加,关注请收藏)
4)欢迎大家关注我博客更多的精彩内容:[http://blog.csdn.net/CleverCode](http://blog.csdn.net/CleverCode)。