美文网首页
php中如何使用的phpspreadsheet插件读取Execl

php中如何使用的phpspreadsheet插件读取Execl

作者: 似朝朝我心 | 来源:发表于2021-06-13 14:27 被阅读0次

    声明:首先php版本必须要到7.2或以上,其次必须安装了composer工具,因为这是一个自动处理依赖包的安装工具,相当node的npm或者说是linux里面的yum,因为这是安装phpspreadsheet插件的必须环境,phpspreadsheet这个插件就是让我们用来读取Execl表格当中的数据的。

    其次是要开启php.ini当中的两个扩展:

    extension = php_openssl.dll
    extension = php_fileinfo.dll
    

    我们可以到getcomposer.org的官网搜一下phpspreadsheet这个插件,下面有一个安装要求:提示你php版本必须在7.2以上。



    如果你已经搭建好了基本环境,那么就可以在项目当中,通过cmd创建:

    composer require phpoffice/phpspreadsheet
    

    然后你会看到项目中就会多出一个vendor目录,代表你的phpspreadsheet插件成功安装。



    如何读取Execl表格当中的数据呢?

    首先准备一张Execl表格。



    phpspreadsheet插件提供两种资源引入:execl文件的读取操作和写入操作。

    首先得引入这个文件

    • 读取一个execl文件所需的资源
    #引入资源
    require("./vendor/autoload.php");//相对于自己的路径出发
    use PhpOffice\PhpSpreadsheet\IOFactory;
    
    • 新建一个execl文件并写入数据所需的资源
    #引入资源
    require("./vendor/autoload.php");
    use PhpOffice\PhpSpreadsheet\Spreadsheet;
    

    起步:创建一个spreadsheet对象(分情形)

    spreadsheet对象是PHPSpreadsheet组件的核心类,借助这个spreadsheet对象可以让我们完成对execl文件的读取、创建、修改等各类操作。


    • 如果我们项目当中已经有了一个execl文件,我们只需要这样来创建一个spreadsheet对象,通过一个已经存在的的文件创建spreadsheet对象的方法。
    #引入资源和使用读取资源操作
    require("./vendor/autoload.php");
    use PhpOffice\PhpSpreadsheet\IOFactory;
    #获取文件的保存路径和文件名
    $fileName = './student.xlsx';
    #从已经存在的文件中创建spreadsheet对象
    $spreadSheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($fileName);
    #打印spreadsheet对象查看
    var_dump($spreadSheet);
    
    -------------------------------------------------------------------------------------
    其中创建spreadsheet对象还可以简写成下面这种形式,效果是一样的:
    $spreadSheet = IOFactory::load($fileName);
    

    打印spreadsheet对象查看



    • 如果文件资源来自于表单,也就是说该execl文件是用户通过上传提交过来的,则使用如下方案进行创建spreadsheet对象。
    <?php
    #引入资源和使用读取资源操作
    require("./vendor/autoload.php");
    use PhpOffice\PhpSpreadsheet\IOFactory;
    #获取表单文件域上传的fileName信息
    $fileName = $_FILES["filen_ame"]["tmp_name"]
    #从已经存在的文件中创建spreadsheet对象
    $spreadSheet = IOFactory::load($fileName);
    #打印spreadsheet对象查看
    var_dump($spreadSheet);
    ?>
    
    <!-- html代码 -->
    <form action="#" method="post" enctype="multipart/form-data">
        <input type="file" name="file_name">
        <input type="submit" value="上传">
    </form>
    

    • 创建一个空的execl文件
    <?php
    require("./vendor/autoload.php");
    use PhpOffice\PhpSpreadsheet\spreadSheet;
    $spreadSheet = new SpreadSheet();
    var_dump($spreadSheet);
    

    创建工作表worksheet对象
    在创建完spreadSheet对象后,可以根据需要访问execl文件中任何一张工作表。

    • 读取execl文件中的第一张表
    $workSheet = $spreadSheet -> getSheet(0)
    

    通过spreadSheet对象调用其下的getSheet(0)方法,括号内的参数0代表第一张表的序号,此外还可以通过工作的表面名来获取工作表worksheet对象。

    • 和工作表worksheet对象相关的常用方法:
    方法名称 功能说明 调用案例
    getSheetCount 获取execl文件文件中的工作表数量,统计一下一共有多少张工作表,返回一个整数 $spreadSheet -> getSheetCount()
    getSheetNames 获取execl文件中的所有的工作表名,返回的是一个数组 $spreadSheet -> getSheetNames()
    getSheet 以序号的形式获取execl文件当中的工作表,0代表是第一张工作表对象,返回一个工作表对象 $spreadSheet -> getSheet ()
    getSheetByName 以表名获取工作表(只能获取一张工作表的名字),返回一个工作表对象 $spreadSheet -> getSheetByName ('Sheet1')
    setTitle 设置或修改execl文件中工作表的名字 $spreadSheet -> setTitle('Copy of Worksheet 1')
    <?php 
    #引入资源和使用读取资源操作
    require("./vendor/autoload.php");
    use PhpOffice\PhpSpreadsheet\IOFactory;
    #获取文件的保存路径和文件名
    $fileName = './student.xlsx';
    #从已经存在的文件中创建spreadsheet对象
    $spreadSheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($fileName);
    
    #统计工作表的数量
    $workSheet = $spreadSheet -> getSheetCount();
    echo '当前execl文件中,共有'.$workSheet.'张工作表!';
    echo '<hr/>';
    
    #获取文件中的所有的工作表名
    $workSheet = $spreadSheet -> getSheetNames();
    print_r($workSheet);
    echo '<hr/>';
    
    #获取文件中的第一张工作表对象
    $workSheet = $spreadSheet -> getSheet(0);
    // print_r($workSheet);
    echo '<hr/>';
    
    #以工作表的名字获取文件中的工作表对象
    $workSheet = $spreadSheet -> getSheetByName('Sheet1');
     // print_r($workSheet);
    echo '<hr/>';
    ?>
    

    创建好一个工作表对象后,我们就可以根据单元格的位置坐标来访问到指定单元格,继而读取或者设置单元格的值了

    phpspreadsheet插件提供了使用列序号+行序号来定位到你想要获取到的单元格,其表达方式一般分为两种,比如我们想访问“何乐嘉”这个值的话,我们只需要这样表达:B2或者[2,2],其中B2这种取值的方式是最为常见的,而[2,2]这种取值的方式在循环时调用单元格更加方便。


    与单元格相关的常用方法:

    方法名称 功能说明 调用案例
    getCell 获取指定单元格对象 $workSheet -> getCell ('A2')
    getValue 获取指定单元格里面的数据,可以返回字符串、数字、布尔、公式等类型数据 $workSheet -> getCell ('A2') -> getValue()
    getCellByColumnAndRow 获取指定单元格对象,功能一样,表达方式不一样 $workSheet -> getCellByColumnAndRow (2,1)
    setCellValue 给单元格设置值,它是工作表对象的方法 $workSheet -> setCellValue ('A3',TRUE)
    setValue 给单元格设置值,它是单元格对象的方法 $workSheet -> getCell ('A2') -> setValue('言真清')
    getHighestRow 获取execl文件当中最大行的序号(统计一共有多少行),返回的值是数字 $workSheet -> getHighestRow()
    getHighestColumn 获取execl文件当中最大行的列号(单元格有值的最末尾那一列的列号,即获取截止的列号) $workSheet -> getHighestColumn()

    案例代码

    参照图:


    <?php
    #引入资源和使用读取资源操作
    require("./vendor/autoload.php");
    use PhpOffice\PhpSpreadsheet\IOFactory;
    #获取文件的保存路径和文件名
    $fileName = './student.xlsx';
    #从已经存在的文件中创建spreadsheet对象
    $spreadSheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($fileName);
    
    #获取execl文件中的第一张工作表对象
    $workSheet = $spreadSheet -> getSheet(0);
    
    #读取单元格B3的值
    $value =  $workSheet -> getCell('B3') -> getValue();
    echo '单元格B3的值为:'.$value;
    echo '<hr/>';
    
    #使用变量标记单元格坐标
    $id = 3;
    $value =  $workSheet -> getCell('B'.$id) -> getValue();
    echo '单元格B3的值为:'.$value;
    echo '<hr/>';
    
    #给单元格设置新值,只是一个缓存状态,并不会真实修改单元格的值,要真实去修改必须借助数据库
    $value =  $workSheet -> getCell('B4') -> setValue('大白');
    echo '设置单元格B4的值为:'.$value;
    echo '<hr/>';
    
    #获取最大的行号(所有行),用于遍历取值
    $rows = $workSheet -> getHighestRow();
    echo '最大行号到第:'.$rows.'行';
    echo '<hr/>';
    #读取第二列所有单元格的值
    for($i=2;$i<$rows;$i++){//从第二行开始
        $rowCell[] = $workSheet -> getCell('B'.$i) -> getValue();
    }
    echo '第二列单元格的所有值:';
    var_dump($rowCell);
    echo '<hr/>';
    
    #获取截止列号,即获取所有列(一般用于遍历取值)
    $columns = $workSheet -> getHighestColumn();
    echo '截止列号到第:'.$columns.'列';
    echo '<hr/>';
    #读取第一行所有单元格的值
    /* 因为列号是大写字母(字符串),所以不能用
    <=来作为for循环的第二个表达式的判断符合,但这样有格bug不能拿到最后一列,而且现在7.1版本后还报错了 */
    // for($col = "A";$col != $columns;$col++){//从A列开始到末列
    //  $colCell[] = $workSheet -> getCellByColumnAndRow($col,1) -> getValue();
    // }
    for($col = 1;$col <= 9;$col++){//从A列开始到末列
        $colCell[] = $workSheet -> getCellByColumnAndRow($col,1) -> getValue();
    }
    echo '第一行单元格的所有值:';
    var_dump($colCell);
    echo '<hr/>';
    ?>
    

    将execl表格的数据通过预处理语句插入数据库

    其次准备搭建数据库:

    school.sql

    create database school;
    use school;
    create table student
    (
        stu_id int(10) unsigned primary key not null,
        stu_name varchar(20) not null,
        stu_class varchar(30)
    );
    
    create table score
    (
       sc_id int auto_increment primary key not null,
       foreign key(stu_id) references student(stu_id)
       on delete cascade
       on update cascade,
       stu_id int(10) unsigned not null,
       sc_normal float(3,1),
       sc_lab float(3,1),
       sc_midterm float(3,1),
       sc_final float(3,1),
       sc_overall float(3,1) not null
    );
    
    
    提示:如果增添了这个on delete cascade,代表因约束不能删除table,
    

    读入学生表信息:

    <?php
    #创建数据库连接对象
    $mysqli = @new mysqli('localhost','root','12345678','school');
    if($mysqli -> connect_error) {
        die('连接数据库失败:'.$mysqli -> connect_error);
    }
    
    #引入资源和使用读取资源操作
    require("./vendor/autoload.php");
    use PhpOffice\PhpSpreadsheet\IOFactory;
    #获取文件的保存路径和文件名
    $fileName = './student.xlsx';
    #从已经存在的文件中创建spreadsheet对象
    $spreadSheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($fileName);
    
    #获取execl文件中的第一张工作表对象
    $workSheet = $spreadSheet -> getSheet(0);
    
    #获取最大的行号(所有行),用于遍历取值
    $rows = $workSheet -> getHighestRow();
    
    #sql语句
    $sql = "insert into student(stu_id,stu_name,stu_class) 
            values(?,?,?)";
    
    #判断一下预处理失败的情况
    if(!($mysqli_stmt = $mysqli -> prepare($sql))){
        die('预处理失败');
    }
    
    #获取A、B、C列单元格的值:分别对应数据库的学号、姓名、班级
    for($i=2;$i<$rows;$i++){//从第二行开始
        $stuId = $workSheet -> getCell('A'.$i) -> getValue();
        $stuName = $workSheet -> getCell('B'.$i) -> getValue();
        $stuClass = $workSheet -> getCell('C'.$i) -> getValue();
        #绑定参数
        $mysqli_stmt -> bind_param('iss',$stuId,$stuName,$stuClass);
        #执行预处理语句
        $mysqli_stmt -> execute();
        if ($mysqli_stmt -> affected_rows == 1) {
            #数据增加成功
            $count ++;#统计一下读入个数
        }
    }
    if($count > 0){
        #写入成功
        echo <<< end
        <script>
            alert("成功录入{$count}个学生的信息");
            location = "./index.php";
        </script>
    end;
    }else {
        #写入失败
        echo <<< end
        <script>
            alert("写入失败");
            location = "./index.php";
        </script>
    end;
    }
    ?>
    


    读入成绩表信息:
    其中总评成绩要经过计算:总评成绩 = 平时成绩的50% + 期末成绩的50%

    <?php
    #创建数据库连接对象
    $mysqli = @new mysqli('localhost','root','12345678','school');
    if($mysqli -> connect_error) {
        die('连接数据库失败:'.$mysqli -> connect_error);
    }
    
    #引入资源和使用读取资源操作
    require("./vendor/autoload.php");
    use PhpOffice\PhpSpreadsheet\IOFactory;
    #获取文件的保存路径和文件名
    $fileName = './student.xlsx';
    #从已经存在的文件中创建spreadsheet对象
    $spreadSheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($fileName);
    
    #获取execl文件中的第一张工作表对象
    $workSheet = $spreadSheet -> getSheet(0);
    
    #获取最大的行号(所有行),用于遍历取值
    $rows = $workSheet -> getHighestRow();
    
    #sql语句
    $sql = "insert into score
            (stu_id,sc_normal,sc_lab,sc_midterm,sc_final,sc_overall) 
            values(?,?,?,?,?,?)";
    
    #判断一下预处理失败的情况
    if(!($mysqli_stmt = $mysqli -> prepare($sql))){
        die('预处理失败');
    }
    
    #获取A、D、E、F、G、H列单元格的值:分别对应数据库的学号、平时成绩、期中成绩、实验成绩、期末成绩、总评成绩
    for($i=2;$i<$rows;$i++){//从第二行开始
        $stu_id = $workSheet -> getCell('A'.$i) -> getValue();
        $sc_normal = $workSheet -> getCell('D'.$i) -> getValue();
        $sc_lab = $workSheet -> getCell('E'.$i) -> getValue();
        $sc_midterm  = $workSheet -> getCell('F'.$i) -> getValue();
        $sc_final = $workSheet -> getCell('G'.$i) -> getValue();    
        $sc_overall = $sc_normal * 0.5 + $sc_final * 0.5; 
        
        #绑定参数
        $mysqli_stmt -> bind_param('iiiiii',$stu_id,$sc_normal,$sc_lab,$sc_midterm,$sc_final,$sc_overall);
        #执行预处理语句
        $mysqli_stmt -> execute();
        if ($mysqli_stmt -> affected_rows == 1) {
            #数据增加成功 
            $count ++;
        }
    }
    if($count > 0){
        #写入成功
        echo <<< end
        <script>
            alert("成功录入{$count}个学生成绩");
            location = "./index.php";
        </script>
    end;
    }else {
        #写入失败
        echo <<< end
        <script>
            alert("写入失败");
            location = "./index.php";
        </script>
    end;
    }
    ?>
    

    多表查询将插入的数据显示到页面上

    <?php
    #创建数据库连接对象
    $mysqli = @new mysqli('localhost','root','12345678','school');
    if($mysqli -> connect_error) {
        die('连接数据库失败:'.$mysqli -> connect_error);
    }
    #sql语句
    $sql = "select student.stu_id,stu_name,stu_class,sc_id,sc_normal,sc_lab,sc_midterm,sc_final,sc_overall   
            from student,score
            where student.stu_id = score.stu_id";
    #准备预处理
    $mysqli_stmt = $mysqli -> prepare($sql);
    #绑定结果
    $mysqli_stmt -> bind_result($stu_id,$stu_name,$stu_class,$sc_id,$sc_normal,$sc_lab,$sc_midterm,$sc_final,$sc_overall);
    #执行预处理
    $mysqli_stmt -> execute();
    #获取所有结果集信息
    $mysqli_stmt -> store_result();
    #获取一条记录
    // $mysqli_stmt -> fetch();
    // echo $stu_class;
    ?>
    
    <!DOCTYPE html>
    <html lang="zh">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <meta http-equiv="X-UA-Compatible" content="ie=edge">
            <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
            <title></title>
        </head>
        <body>
            <div id="app">
            <table border="1">
                <tr>
                    <th v-for="(item,index) in titleList" :key="index">{{item}}</th>
                </tr>
    <?php
             if($mysqli_stmt -> num_rows == 0){
                echo '没有获取到数据';
             }else {
                while ($mysqli_stmt -> fetch()) {
                echo <<< end
                <tr style="text-align: center;">
                    <td>$sc_id</td>
                    <td>$stu_id</td>
                    <td>$stu_name</td>
                    <td>$stu_class</td>
                    <td>$sc_normal</td>
                    <td>$sc_midterm</td>
                    <td>$sc_lab</td>
                    <td>$sc_final</td>
                    <td>$sc_overall</td>
                </tr>   
    end;
             }
        }
    ?>
            </table>
            </div>
    
            <script type="text/javascript">
                const app = new Vue({
                    data() {
                        return {
                            title: '11',
                            titleList: ['序号','学号', '姓名', '班级', '平时成绩', '期中成绩', '实验成绩', '期末成绩', '总评成绩', ]
                        }
                    }
                }).$mount("#app")
            </script>
        </body>
    </html>
    
    <?php 
    #释放结果集
    $mysqli_stmt -> free_result();
    #关闭预处理语句
    $mysqli_stmt -> close()
    ?>
    
    

    相关文章

      网友评论

          本文标题:php中如何使用的phpspreadsheet插件读取Execl

          本文链接:https://www.haomeiwen.com/subject/fykmeltx.html