PHP_XLSXWriter 數(shù)據(jù)庫輸出輔助類

為了減輕后期開發(fā)的麻煩亩冬,寫了這個(gè)類,用以簡化輸出配置,自動(dòng)合并表頭樣式

PHP_XLSXWriter : https://github.com/mk-j/PHP_XLSXWriter
先看例子(test.php):

vendor('XLSXWriter.Helper');
$ds=M('kaoqin_tongji')->where("BMID=111 and YueFen='2021-01'")->select();
$writer = new \XLSXWriterHelper();
$writer->writeToStdOutX('統(tǒng)計(jì)導(dǎo)出', [['-', '統(tǒng)計(jì)導(dǎo)出', [
    ['XH', '序號', 8],
    ['BM', '部門', 16],
    ['XM', '姓名', 12],
    ['YCQ', '應(yīng)出勤', 8],
    ['SCQ', '實(shí)際出勤', 10],
    ['SDK', '實(shí)際打卡', 10],
    ['CC', '出差天數(shù)', 10],
    ['JX', '計(jì)薪天數(shù)', 10],
    ['ZMJB', '周末加班', 10],
    ['JRJB', '節(jié)日加班', 10],
    ['-', '請休假', [
        ['NJ', '年假', 6],
        ['HJ', '婚假', 6],
        ['PCJ', '陪產(chǎn)假', 8],
        ['SAJ', '喪假', 6],
        ['CJ', '產(chǎn)假', 6],
        ['GSJ', '工傷假', 8],
        ['SJ', '事假', 6],
        ['BJ', '病假', 6],
    ]],
    ['-', '夜值', [
        ['YZ1', '夜值A(chǔ)', 8],
        ['YZ2', '夜值B', 8],
    ]],
]]], $ds);
導(dǎo)出效果

輔助類 Helper.php:

<?php

require_once 'XLSXWriter.class.php';

class XLSXWriterHelper
{
    private function getHdsWidths($hds)
    {
        $re = [];
        foreach ($hds as $hid => $h) {
            foreach ($h as $lid => $l) {
                if (array_key_exists(1, $l) && (int) $l[1] > 0) {
                    $re[$lid] = (int) $l[1];
                }
            }
        }

        return $re;
    }

    private function getHdsRowFs($hds)
    {
        $re = [];
        foreach ($hds as $hid => $h) {
            foreach ($h as $lid => $l) {
                if (array_key_exists(2, $l)) {
                    $re[$lid] = $l[2];
                }
            }
        }

        return $re;
    }

    private function getHdsRowDs($hds)
    {
        $re = [];
        $lm = 0;
        foreach ($hds as $hid => $h) {
            $ls = max(array_keys($h));
            if ($ls > $lm) {
                $lm = $ls;
            }
        }
        foreach ($hds as $hid => $h) {
            $re[$hid] = array_pad([], $lm, '');
            foreach ($h as $lid => $l) {
                $re[$hid][$lid] = $l[0];
            }
        }

        return $re;
    }

    private function getHdsMergeInfo($hds)
    {
        $re = [];
        foreach ($hds as $hid => $h) {
            foreach ($h as $lid => $l) {
                if (array_key_exists('merge', $l)) {
                    $re[] = $l['merge'];
                } else {
                    if (!empty($l[0]) && $hid < (count($hds) - 1) && $hds[$hid + 1][$lid][0] == '') {
                        $re[] = [$hid, $lid, $hid + 1, $lid];
                    }
                }
            }
        }

        return $re;
    }

    private function config2HDS($config, &$hds, $h = 0, $l = 0)
    {
        $hs = [];
        $i = -1;
        foreach ($config as $v) {
            ++$i;
            if (!array_key_exists($h, $hds)) {
                $hds[$h] = [];
            }

            if ($v[0] == '-') {
                $w = self::config2HDS($v[2], $hds, $h + 1, $l + $i);
                $hds[$h][$l + $i] = [$v[1], 'merge' => [$h, $l + $i, $h, $l + $i + $w]];
                for ($k = 1; $k <= $w; ++$k) {
                    $hds[$h][$l + $i + $k] = [''];
                }
                $i += $w;
            } else {
                $hds[$h][$l + $i] = [$v[1], $v[2], $v[0]];
            }
        }

        return $i;
    }

    public static function writeToStdOutX($filename = '導(dǎo)出', $config = [], $ds = [])
    {
        ob_end_clean();
        ob_start();
        header('Content-Disposition:attachment;filename='.$filename.'.xlsx');
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header('Content-Transfer-Encoding: binary');
        header('Cache-Control: must-revalidate');
        header('Pragma: no-cache');
        header('Expires: 0');
        $writer = new \XLSXWriter();
        $writer->setTempDir('./Uploadfile/temp');
        $style = ['border' => 'left,right,top,bottom', 'border-style' => 'thin', 'valign' => 'center', 'wrap_text' => 'true', 'height' => 20];

        $hds = [];
        self::config2HDS($config, $hds);
        $hd = self::getHdsRowDs($hds);
        $hw = self::getHdsWidths($hds);
        $hf = self::getHdsRowFs($hds);
        $hm = self::getHdsMergeInfo($hds);
        $hs = [
            'suppress_row' => true,
            'widths' => $hw,
        ];
        $writer->writeSheetHeader('Sheet1', array_pad([], count($hw), 'string'), $col_options = $hs);
        foreach ($hd as $dhi => $dh) {
            $writer->writeSheetRow('Sheet1', $dh, array_merge($style, $dhi == 0 ? ['halign' => 'center',  'font-style' => 'bold'] : ['halign' => 'center']));
        }

        $data = [];
        $i = 0;

        foreach ($ds as $d) {
            $line = [++$i];

            foreach ($hf as $hk => $v) {
                $line[$hk] = $d[$v];
            }
            $data[] = $line;
        }

        foreach ($data as $d) {
            $writer->writeSheetRow('Sheet1', $d, $style);
        }
        foreach ($hm as $mg) {
            $writer->markMergedCell('Sheet1', $start_row = $mg[0], $start_col = $mg[1], $end_row = $mg[2], $end_col = $mg[3]);
        }
        $writer->writeToStdOut();
        die;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市又厉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌欣孤,老刑警劉巖馋没,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異降传,居然都是意外死亡篷朵,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門婆排,熙熙樓的掌柜王于貴愁眉苦臉地迎上來声旺,“玉大人,你說我怎么就攤上這事段只∪” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵赞枕,是天一觀的道長澈缺。 經(jīng)常有香客問我,道長炕婶,這世上最難降的妖魔是什么姐赡? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮柠掂,結(jié)果婚禮上项滑,老公的妹妹穿的比我還像新娘。我一直安慰自己涯贞,他們只是感情好枪狂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著宋渔,像睡著了一般州疾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上皇拣,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天严蓖,我揣著相機(jī)與錄音,去河邊找鬼。 笑死谈飒,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的态蒂。 我是一名探鬼主播杭措,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼钾恢!你這毒婦竟也來了手素?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤瘩蚪,失蹤者是張志新(化名)和其女友劉穎泉懦,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體疹瘦,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡崩哩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了言沐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片邓嘹。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖险胰,靈堂內(nèi)的尸體忽然破棺而出汹押,到底是詐尸還是另有隱情,我是刑警寧澤起便,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布棚贾,位于F島的核電站,受9級特大地震影響榆综,放射性物質(zhì)發(fā)生泄漏妙痹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一奖年、第九天 我趴在偏房一處隱蔽的房頂上張望细诸。 院中可真熱鬧,春花似錦陋守、人聲如沸震贵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽猩系。三九已至,卻和暖如春中燥,著一層夾襖步出監(jiān)牢的瞬間寇甸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拿霉,地道東北人吟秩。 一個(gè)月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像绽淘,于是被迫代替她去往敵國和親涵防。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容