ThinkPhp 使用PhpExcel导出导入多语言文件

ThinkPHP 里已经实现了多语言功能,只要在指定的目录下创建对应的语言文件并填充内容,即可实现多语言功能

而多语言的翻译却是一个很麻烦的事情,因为客户特定的行业问题导致我们翻译可能是不准确的

于是就写了一个导入导出多语言功能,让客户根据规则自行翻译多语言内容(撇清责任)

ThinkPHP 具体的语言包文件命名和位置如下:

 

语言包语言文件位置
应用语言包 应用公共目录/Lang/语言文件.php
模块语言包 模块目录/Lang/语言文件.php
控制器语言包 模块目录/Lang/语言目录/控制器名(小写).php

 

 

 

 

<?php
/**
 * @Author:      HTL
 * @Email:       Huangyuan413026@163.com
 * @DateTime:    2016-07-13 17:06:00
 * @Description: 多语言导出与导入
 */
namespace Admin\Controller;
use Common\Controller\AdminbaseController;
class LangController extends AdminbaseController
{
 
    /**
     * 首页
     * @Author   HTL
     * @Email    huangyuan413026@163.com
     * @DateTime 2016-07-13T17:11:40+0800
     * @return   [type]                   [description]
     */
    function index()
    {
        switch (I("get.type")) {
            case 'export_lang':
                $this->_export_lang();
                break;
            case 'import_lang':
                $this->_import_lang();
                break;
            default:
                $this->display();
                break;
        }
    }
    /**
     * 从Excel中导入多语言并生成PHP代码
     * @Author   HTL
     * @Email    huangyuan413026@163.com
     * @DateTime 2016-07-12T17:08:42+0800
     * @return   [type]                   [description]
     */
    function _import_lang()
    {
        //是否上传文件
        if (count($_FILES['file']) <= 0) {
            $this->error("not select file");
            exit;
        }
        //多语言路径,注意路径大小写,Linux是区分大小写的
        $lang_path = SPAPP . "Admin/Lang/";
        $apps = sp_scan_dir($lang_path . "/*", GLOB_ONLYDIR);
        //多语言数[提供几种语言]
        $app_count = count($apps);
        if ($app_count <= 0) {
            $this->error(L("_SELECT_NOT_EXIST_"));
            exit;
        }
        //将上传的多语言文件上传到此,需要有写入权限
        $new_file = './data/upload/' . iconv('UTF-8', 'GB2312', $_FILES['file']['name']);
        //上传到指定路径
        move_uploaded_file($_FILES['file']['tmp_name'], $new_file);
        vendor("PHPExcel.PHPExcel");
        //导入PHPExcel类
        $objPHPExcel;
        try {
            $objReader = \PHPExcel_IOFactory::createReader('Excel2007');
            $objPHPExcel = $objReader->load($new_file);
        } catch (Exception $e) {
            $this->error($e->getMessage());
            die;
        }
        //遍历工作表
        foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
            $excels = array();
            $highestRow = $worksheet->getHighestRow();
            foreach ($worksheet->getRowIterator() as $row_index => $row) {
                //得到所有列
                $cellIterator = $row->getCellIterator();
                //单元格索引
                $index = 0;
                //遍历列
                foreach ($cellIterator as $cell_index => $cell) {
                    //多语言的名称[en-us、zh-cn 、more.......]
                    //根据多语言生成不同的数组[每个语言为一个数组]
                    if ($row_index == 1) {
                        break;
                        //导出的文档语言是否本地的语言一致
                        // $lang_name = $cell->getCalculatedValue();
                        // foreach ($apps as $key => $value) {
                        //  $excels[$value] = array();
                        // }
                    }
                    //创建多语言数据[0=多语言的字段]
                    //某个语言的字段,用于设置N个多语言的值
                    if ($index == 0) {
                        $lang_name = $cell->getCalculatedValue();
                    } else {
                        $cell_val = $cell->getCalculatedValue();
                        //设置某个语言的字段值
                        if (strlen($cell_val) > 0) {
                            $excels[$apps[$index - 1]][$lang_name] = $cell_val;
                        }
                    }
                    $index++;
                }
            }
            //输出php代码到文件
            //$name:语言名称
            //$excl:语言内容
            foreach ($excels as $name => $excel) {
                $excel = var_export($excel, true);
                //var_export 生成的数组有一个空值,需要去掉,否则将出现错误
                $excel = preg_replace("/\\,\\s\\)/i", ")", $excel);
                //输出php语言格式
                $excel = "<?php return " . $excel . "?>";
                if ($worksheet->getTitle() == "ALL_Language.php") {
                    file_put_contents($lang_path . '/' . $name . ".php", $excel);
                } else {
                    file_put_contents($lang_path . '/' . $name . '/' . $worksheet->getTitle(), $excel);
                }
            }
        }
        unset($excels);
        unset($objPHPExcel);
        $this->success(L("_OPERATION_SUCCESS_"));
    }
    /**
     * 替代scan_dir的方法
     * @param string $pattern 检索模式 搜索模式 *.txt,*.doc; (同glog方法)
     * @param int $flags
     */
    function sp_scan_dir($pattern, $flags = null)
    {
        $files = array_map('basename', glob($pattern, $flags));
        return $files;
    }
    /**
     * 导出自定义多语言到excel
     * @Author   HTL
     * @Email    huangyuan413026@163.com
     * @DateTime 2016-07-12T16:23:36+0800
     * @return   [type]                   [description]
     */
    function _export_lang()
    {
        //多语言文件所在路径,注意大小写
        $lang_path = SPAPP . "Admin/Lang/";
        $apps = sp_scan_dir($lang_path . "/*", GLOB_ONLYDIR);
        //多语言数[提供几种语言]
        $app_count = count($apps);
        if ($app_count <= 0) {
            $this->error(L("_SELECT_NOT_EXIST_"));
            exit;
        }
        vendor("PHPExcel.PHPExcel");
        //导入PHPExcel类
        $objPHPExcel = new \PHPExcel();
        $app = $lang_path . $apps[0];
        if (!is_dir($app)) {
            $this->error(L("_SELECT_NOT_EXIST_"));
            exit;
        }
        $objPHPExcel->removeSheetByIndex(0);
        //路径下的语言文件[/lang/en-us.php & /Lang/zh-cn.php & more]
        $merge_files = array();
        foreach ($apps as $key => $value) {
            $lang_file = $lang_path . $value . '.php';
            if (is_file($lang_file)) {
                //数组的key为多语言名称
                $merge_files[$value] = (include $lang_file);
            }
            //end if
        }
        //end foreach
        // print_r($merge_files);exit;
        // ALL_Language.php 为全局语言文件
        $this->_set_sheet_value(0, $objPHPExcel, $merge_files, 'ALL_Language.php');
        //多语言目录下的语言文件[/Lang/zh-cn/*.php]
        $files = sp_scan_dir($app . "/*.php");
        foreach ($files as $index => $key) {
            //合并多语言到一个数组
            $merge_files = array();
            //导入多语言并添加到数组中
            foreach ($apps as $_app) {
                $lang_file = $lang_path . $_app . '/' . $key;
                // echo($_app).'<BR>';
                // array_push($merge_files, $_app);
                if (is_file($lang_file)) {
                    //数组的key为多语言名称
                    $merge_files[$_app] = (include $lang_file);
                    // array_push($merge_files, include ($lang_file));
                }
                //end if
            }
            //end foreach
            $this->_set_sheet_value($index + 1, $objPHPExcel, $merge_files, $key);
        }
        //end forach
        $objPHPExcel->setActiveSheetIndex(0);
        // $objPHPExcel->removeSheetByIndex(0);
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header('Content-Disposition: attachment;filename="' . date('ymdHis') . '-Languages.xlsx"');
        header('Cache-Control: max-age=0');
        // If you're serving to IE 9, then the following may be needed
        header('Cache-Control: max-age=1');
        // If you're serving to IE over SSL, then the following may be needed
        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
        // Date in the past
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
        // always modified
        header('Cache-Control: cache, must-revalidate');
        // HTTP/1.1
        header('Pragma: public');
        // HTTP/1.0
        $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
        $objWriter->save('php://output');
    }
    /**
     * 设置sheet和单元格值
     * @Author   HTL
     * @Email    huangyuan413026@163.com
     * @DateTime 2016-07-12T17:06:05+0800
     * @param    [type]                   $sheet_index [sheet的索引]
     * @param    [type]                   $objPHPExcel [phpexcel对象]
     * @param    [type]                   $merge_files [多语言数据]
     * @param    [type]                   $title       [sheet title]
     */
    function _set_sheet_value($sheet_index = 0, $objPHPExcel, $merge_files, $title)
    {
        if (!$objPHPExcel || !$objPHPExcel || count($objPHPExcel) <= 0) {
            return;
        }
        //创建sheet并设置title,每一个多语言文件都是一个sheet
        $excel = $objPHPExcel->createSheet($sheet_index)->setTitle($title);
        // $excel->setCellValue('A1',"Name")->setCellValue('B1',"")->setCellValue("C1","");
        //多语言定义的字段数量
        $field_count = array_keys($merge_files);
        //计算第一个多语言的key数量[数组的key是多语言名称: array=('zh-cn'=>array("name"=>"name","age"=>"age"),"en-us"=>array())]
        $field_count = array_keys($merge_files[$field_count[0]]);
        //行索引[excel从1开始]
        $row_index = 1;
        //设置多语言
        foreach ($merge_files as $_key => $_value) {
            //每个shet的第一行第一列为Name[字段的名称]
            if ($row_index == 1) {
                $excel->setCellValue("A{$row_index}", "Name");
            }
            //第一行的其他列为多语言名称[zh-cn、en-us、.....]
            $excel->setCellValue(\PHPExcel_Cell::stringFromColumnIndex($row_index) . '1', $_key);
            //每个多语言都是单独一列
            foreach ($field_count as $key => $values) {
                //第一列为多语言字段名[从1开始,第1行为Name或多语言名称,因此这里从2开始]
                $excel->setCellValue('A' . ($key + 2), $field_count[$key]);
                //列索引
                $column_index = \PHPExcel_Cell::stringFromColumnIndex($row_index);
                $excel->setCellValue($column_index . '' . ($key + 2), $_value[$values]);
            }
            //end foreach
            $row_index++;
        }
        //end foreach
    }
}

 

 
导出的多语言文件,每一个文件就是一个sheet,不同的多语言会合同到同一个sheet里
因为根目录下有两个多语言文件zh-cn.php,en-us.php在非子目录下,所以将这两个文件放在一个单独的sheet(ALL_Language)里单独处理
 
因为code里的多语言路径是固定的,所以只会处理:f:\WWW\application\Admin\Lang\*.php文件
 
导入的php格式如下
 
 
参考:





posted @ 2017-03-15 15:45  HTL  阅读(475)  评论(0编辑  收藏  举报
htl