v枫叶v

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

ThinkPHP CSV导入与导出


在thinkphp/library/think下新建Csv.php文件,这个看个人习惯能引用到就可以了,以此为例
<?php
namespace Think;
class Csv
{
    //导出csv文件
    public function put_csv($list,$title)
    {
        $file_name = "exam".time().".csv";
        header("Content-Type: application/octet-stream");
        header("Content-Transfer-Encoding: binary");
        header('Expires: '.gmdate('D, d M Y H:i:s').' GMT');
        header('Content-Disposition: attachment; filename = "'.$file_name);
        header('Pragma: no-cache');
        $file = fopen('php://output',"a");
        $limit = 1000;
        $calc = 0;
        foreach ($title as $v){
            $tit[] = iconv('UTF-8', 'GB2312//IGNORE',$v);
        }
        fputcsv($file,$tit);
        foreach ($list as $v){
            $calc++;
            if($limit == $calc){
                ob_flush();
                flush();
                $calc = 0;
            }
            foreach($v as $t){
                $tarr[] = iconv('UTF-8', 'GB2312//IGNORE',$t);
            }
            fputcsv($file,$tarr);
            unset($tarr);
        }
        unset($list);
        fclose($file);
        exit();
    }
   
    // csv导入 
    public function input_csv($csv_file) {  
        $result_arr = array ();  
        $i = 0;  
        while($data_line = fgetcsv($csv_file,10000)) { //10000是表示可以处理多长的字符 
            if ($i == 0) {  
                $GLOBALS ['csv_key_name_arr'] = $data_line;  
                $i ++;  
                continue;  
            }      
            foreach($GLOBALS['csv_key_name_arr'] as $csv_key_num => $csv_key_name ) {  
                $result_arr[$i][$csv_key_name] = $data_line[$csv_key_num];  
            }  
            $i++;  
        }  
        return $result_arr;  
    }  
}
?>
接下来是控制器调用
  • 1
<?php
namespace app\index\controller;
use think\Controller;
use think\Request;
use think\Db;
use think\Paginator;
use think\Validate;
use think\Csv;  //此处是csv文件实现的关键
class Index extends Controller
{
    public function _initialize()
    {
      header("Content-type:text/html;charset=utf-8");
    }    
    /*
     * CSV试题导出
     */
    public function downQuestions()
    {       
        $csv = new Csv(); 
        $serial_sta = intval(Request::param('serial_sta'));
        $serial_end = intval(Request::param('serial_end'));
        $id = intval(Request::param('id'));
        for($i=$serial_sta;$i<=$serial_end;$i++){
            $data[$i]['id'] = "$i";
            $data[$i]['url'] = "http://47.104.212.117:8081/resource/scan_index?prodId=".$id."&serial_num=".$i;
        }
        $title = ['产品编号','二维码地址'];
        $csv->put_csv($data,$title);
    }
    
    /*
     * CSV试题导入
     */   
    public function upQuestionsWrite()
    {
        // 获取表单上传文件
        $file = request()->file('examfile');
        if(empty($file)) {
            $this->error('请选择上传文件');
        }
        // 移动到框架应用根目录/public/uploads/ 目录下
        $info = $file->move(ROOT_PATH.'public'.DS.'upload'); 
        //获取文件(日期/文件),$info->getFilename();
        $filename = ROOT_PATH.'public'.DS.'upload/'.$info->getSaveName();
        $handle = fopen($filename,'r');
        $csv = new Csv();  
        $result = $csv->input_csv($handle); // 解析csv  
        $len_result = count($result);  
        if($len_result == 0){  
            $this->error('此文件中没有数据!');
        }  
        $data_values = '';  
        for($i = 1;$i < $len_result+1;$i ++) { // 循环获取各字段值  
            $arr = array_values($result[$i]);  
            $qu_name = iconv('gb2312','utf-8',$arr[0] ); // 中文转码  
            $qu_options = iconv('gb2312','utf-8',$arr[1]);  
            $qu_answer = $arr[2];  
            $qu_describe = iconv('gb2312','utf-8',$arr[3]);
            $to_id = $arr[4]; 
            $te_id = 1; //添加试题的教师           
            $data_values .= "('$qu_name','$qu_options','$qu_answer','$qu_describe','$to_id','$te_id'),";  
        }  
        $data_values = substr($data_values,0,- 1 ); // 去掉最后一个逗号  
        fclose($handle); // 关闭指针
        // 批量插入数据表中
        $result = DB::execute("insert into gw_questions (qu_name,qu_options,qu_answer,qu_describe,to_id,te_id) values $data_values" );
        if($result){            
            $this->success('文件上传成功,数据已经导入!','exampaper',3);
        }else{
            // 上传失败获取错误信息
            $this->error($file->getError());
        }
    }   
}
?> 
  • 1
模板页表单(此处我的项目中使用了layui,样式可以按自己的需求修改)
  • 1
layui.use(['form', 'table'], function () {
        var $ = layui.jquery,
            form = layui.form,
            table = layui.table;

        table.render({
            elem: '#currentTableId',
            url: "{:url('index')}",
            method:"post",
            toolbar: '#toolbar',
            defaultToolbar: ['filter',, {
                title: '提示',
                layEvent: 'LAYTABLE_TIPS',
                icon: 'layui-icon-tips'
            }],
            cols: [[
                {type: "checkbox", width: 50, fixed: "left"},
                {field: 'id', width: 80, title: 'ID', sort: true},
                {field: 'name', width: 100, title: '产品名称'},               
                {field: 'publisher', width: 100, title: '出品方'},
                {field: 'producer', width: 100, title: '生产方'},
                {field: "produce_from", width: 180, title: '产地'},
                {field: 'price', width: 100, title: '零售价'},
                {field: 'info', width: 150, title: '产品信息'},
                {field: 'serial_num', width: 150, title: '内部编号'},
                {field: 'serial_sta', width: 130, title: '批次起始编码'},
                {field: 'serial_end', width: 130, title: '批次结束编码'},
                {field: 'num', width: 100, title: '批次数量'},
                {field: 'auth_status', width: 100, title: '审核状态', templet: '#auth_status', align: 'center'},
                {templet: '#csv', align: 'center', title: 'csv生成', width: 80},
                {title: '操作', minWidth: 50, templet: '#currentTableBar', fixed: "right", align: "center"}
            ]],
            limits: [10, 15, 20, 25, 50, 100],
            limit: 15,
            page: true
        });
js方面的代码,粗略的复制了一下,具体需求自行修改
table.on('tool(currentTableFilter)', function (obj) {
	  var data = obj.data;
	    if(obj.event === 'csv'){
	        window.location.href = "{:url('getcsv')}?serial_sta="+data.serial_sta+'&serial_end='+data.serial_end+'&id='+data.id;
	    }
});

 

这里注意:有很多人用ajax传值到后台进行操作,我简单试了下,这样会导致文本在浏览器直接输出,并不会浏览器下载,我这里直接跳转是可以的,有什么好的方法可以自己研究一下。

posted on 2022-06-25 11:18  v枫叶v  阅读(124)  评论(0)    收藏  举报