2015/11/26

phpexcel获取单元格合并值


在上一次博客中(http://www.yangxg.com/blog/3125783848.html),提到使用phpexcel进行数据的导出。如果xls表不涉及 到单元格合并的话,是没什么问题,数据会如愿的导出。现在的问题是:假如我的item.xls表里面,道具描述二做了合并, 如图下

phpexcelmerge_01.png

那么导出结果将会变成:

<?php

//道具数据
$setting_data["ItemData"] = array (
  1001 =>
  array (
    'ItemId' => 1001,
    'Name' => '气血包',
    'Desc1' => '恢复800点血量',
    'Desc2' => '此道具只能在战斗中使用',
  ),
  1002 =>
  array (
    'ItemId' => '1002',
    'Name' => '超级气血包',
    'Desc1' => '恢复100%点血量',
  ),
);

1002一行数据中,Desc2字段值为空。这就不是我想要的结果。excel表规定合并单元格时,数据只会保留最左上角的值,其他值将置空。

phpexcelmerge_02.png


既然这样,我们要使得合并单元格的值都是最左上角的值,就必须做到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