在上一次博客中(http://www.yangxg.com/blog/3125783848.html),提到使用phpexcel进行数据的导出。如果xls表不涉及 到单元格合并的话,是没什么问题,数据会如愿的导出。现在的问题是:假如我的item.xls表里面,道具描述二做了合并, 如图下
那么导出结果将会变成:
<?php
//道具数据
$setting_data["ItemData"] = array (
1001 =>
array (
'ItemId' => 1001,
'Name' => '气血包',
'Desc1' => '恢复800点血量',
'Desc2' => '此道具只能在战斗中使用',
),
1002 =>
array (
'ItemId' => '1002',
'Name' => '超级气血包',
'Desc1' => '恢复100%点血量',
),
);
1002一行数据中,Desc2字段值为空。这就不是我想要的结果。excel表规定合并单元格时,数据只会保留最左上角的值,其他值将置空。
既然这样,我们要使得合并单元格的值都是最左上角的值,就必须做到2点:
1. 明确知道有哪些单元格已被合并。
2. 将合并的单元格值都设置为最左上角的值。
PHPExcel_Worksheet::getMergeCells()
,此接口可以获取当前工作表中所有做过合并的单元格信息,它返回的是一个数组,每一条内容都记录着合并单元格左上角和右下角的位置信息。
但是需要特别特别注意,千万不能设置为只读模式($reader->setReadDataOnly(true)
),否则上面接口将会失去效用。这个问题坑了我一个早上,呵呵。
既然能够获取到所有的合并单元格信息,那么接下来就很好办了,直接贴上最主要部分代码:
$sheetdata = $sheet->toArray();
//兼容合并单元格 注意此接口, 如果你设置了 $reader->setReadDataOnly(true), 那么此接口将返回空值
//数据样式: Array( ["D5:D6"] => "D5:D6", )
$mergeCells = $sheet->getMergeCells();
foreach ($mergeCells as $key => $value) {
$var = explode(":", $value);
list($fc, $fr) = PHPExcel_Cell::coordinateFromString($var[0]);//把单元格名分为 列, 行 (eg: D,5)
$fc = PHPExcel_Cell::columnIndexFromString($fc) - 1;//把字母列转换为数值 (eg: D转换后为4)
list($lc, $lr) = PHPExcel_Cell::coordinateFromString($var[1]);
$lc = PHPExcel_Cell::columnIndexFromString($lc) - 1;
$tmpvalue = $sheetdata[($fr-1)][$fc];//最左上角值
$r = $fr - 1;
while($r++ < $lr) {
$c = $fc - 1;
while($c++ < $lc) {
$sheetdata[$r-1][$c] = $tmpvalue;//将合并的单元格全部设置为最左上角值
}
}
}
全新导表版本已经提交到github: https://github.com/yangxgkem/genxls