excel格式

excel中xls和xlsx的区别是:

1、文件格式不同。
xls是一个特有的二进制格式,其核心结构是复合文档类型的结构,
xlsx的核心结构是XML类型的结构,采用的是基于 XML 的压缩方式,使其占用的空间更小。xlsx 中最后一个 x 的意义就在于此。(即:docx取代doc、.xlsx取代xls等等)
2、版本不同。xls是excel2003及以前版本生成的文件格式,而xlsx是excel2007及以后版本生成的文件格式。
3、兼容性不同。xlsx格式是向下兼容的,可兼容xls格式。

cvs

csv本质是text,只是一堆逗号分隔的文本,不带Excel格式,如:你用Excel可以做数据处理,但是cvs这种格式不会保存任何格式相关的东西

php导出excel的原理

https://www.php.cn/php-ask-430015.html
对于excel2003来说,由于其本质是二进制文件,所以,导出excel的过程首先会打开二进制文件,然后读取内部信息,并把内部信息转化为可以识别的内容的过程。
对于excel2007来说,由于其本质为xml的集合文档,所以导出过程就是解析xml的过程;

PHP导出csv,不用任何外部类库文件

PHP有导出csv格式的函数,CSV本质还是文本
fputcsv() 函数将行格式化为 CSV 并写入一个打开的文件
如果要导出xlsx格式的Excel,还需要使用PHPOffice 套件中的 PHPExcel

  1. header("Content-type: text/csv");
  2. header("Content-Disposition: attachment; filename=reply.csv");
  3. header("Pragma: no-cache");
  4. header("Expires: 0");
  5. $output = fopen("php://output", "w");
  6. $header = array('学号','姓名','性别','年龄','班级');
  7. $converter = function($value) {
  8. return iconv('utf-8', 'gbk', $value);
  9. };
  10. $header = array_map($converter, $header);
  11. $list = array(
  12. array('1','小王','男','20','100'),
  13. array('2','小李','男','20','101'),
  14. array('3','小张','女','20','102'),
  15. array('4','小赵','女','20','103')
  16. );
  17. fputcsv($output, $header);
  18. foreach($list as $k => $v)
  19. {
  20. $csvrow = array_map($converter, array(
  21. $v[0],
  22. $v[1],
  23. $v[2],
  24. $v[3],
  25. $v[4],
  26. ));
  27. fputcsv($output, $csvrow);
  28. }
  29. fclose($output);

laravel Excel扩展

本文由 简悦 SimpRead 转码, 原文地址 laravelacademy.org


1、简介

Laravel Excel 在 Laravel 5 中集成 PHPOffice 套件中的 PHPExcel,从而方便我们以优雅的、富有表现力的代码实现 Excel/CSV 文件的导入和导出。

该项目的 GitHub 地址是:https://github.com/Maatwebsite/Laravel-Excel

本文我们将在 Laravel 中使用 Laravel Excel 简单实现 Excel 文件的导入和导出。

文档

现在是版本3了,需要laravel5以上。代码改动很大。
目前使用的还是版本2:
https://docs.laravel-excel.com/2.1/getting-started/

水平对齐:https://docs.laravel-excel.com/2.1/export/cells.html
宽度 https://docs.laravel-excel.com/2.1/export/sizing.html

2、安装 & 配置

使用 Composer 安装依赖

首先在 Laravel 项目根目录下使用 Composer 安装依赖:
composer require maatwebsite/excel 2.1.0

安装后的设置

config/app.php中注册服务提供者到providers数组:
Maatwebsite\Excel\ExcelServiceProvider::class,

同样在config/app.php中注册门面到aliases数组:
‘Excel’ => Maatwebsite\Excel\Facades\Excel::class,

如果想要对 Laravel Excel 进行更多的自定义配置,执行如下 Artisan 命令:
php artisan vendor:publish

执行成功后会在config目录下生成一个配置文件excel.php

3、导出 Excel 文件

为了演示 Laravel Excel 相关功能,我们为本测试创建一个干净的控制器ExcelController.php
php artisan make:controller ExcelController —plain

然后在routes.php中定义相关路由:
Route::get(‘excel/export’,’ExcelController@export’);
Route::get(‘excel/import’,’ExcelController@import’);

接下来我们先在ExcelController.php中定义export方法实现导出功能:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;

use Excel;

class ExcelController extends Controller
{
    //Excel文件导出功能 By Laravel学院
    public function export(){
        $cellData = [
            ['学号','姓名','成绩'],
            ['10001','AAAAA','99'],
            ['10002','BBBBB','92'],
            ['10003','CCCCC','95'],
            ['10004','DDDDD','89'],
            ['10005','EEEEE','96'],
        ];
        Excel::create('学生成绩',function($excel) use ($cellData){

            $excel->sheet('score', function($sheet) use ($cellData){
                $sheet->rows($cellData);
            });
        })->export('xlsx');
    }
}

我们在浏览器中访问[http://laravel.app:8000/excel/export](http://laravel.app:8000/excel/export),会导出一个名为学生成绩.xls的 Excel 文件:
对应sheet(’score’)
https://docs.laravel-excel.com/2.1/export/sheets.html
image.png

如果你要导出 csv 或者 xlsx 文件,只需将export方法中的参数改成 csv 或 xlsx 即可。

如果还要将该 Excel 文件保存到服务器上,可以使用store方法:

文件默认保存到storage/exports目录下,如果出现文件名中文乱码,将上述代码文件名做如下修改即可:

Excel::create('学生成绩',function($excel) use ($cellData){
     $excel->sheet('score', function($sheet) use ($cellData){
         $sheet->rows($cellData);
     });
})->store('xls')->export('xls');

4、导入 Excel 文件

我们将刚才保存到服务器上的 Excel 文件导入进来,导入很简单,使用Excel门面上的load方法即可:

//Excel文件导入功能 By Laravel学院
public function import(){
    $filePath = 'storage/exports/'.iconv('UTF-8', 'GBK', '学生成绩').'.xls';
    Excel::load($filePath, function($reader) {
        $data = $reader->all();
        dd($data);
    });
}

load方法基于项目根路径作为根目录,同样我们对中文进行了转码,否则会提示文件不存在。

在浏览器中访问[http://laravel.app:8000/excel/import](http://laravel.app:8000/excel/import),页面显示如下:

maatwebsite/excel - 图2

当然,Laravel Excel 还有很多其它功能,比如将 Blade 视图导出为 Excel 或 CSV,以及对导入 / 导出更加细粒度的控制,具体可参考其官方文档:http://www.maatwebsite.nl/laravel-excel/docs

源码分析

->export(‘xlsx’);
�这个方法最终会调用这个函数:
vendor/maatwebsite/excel/src/Maatwebsite/Excel/Writers/LaravelExcelWriter.php
image.png
最后将文件内容通过 php://output 写入到输出缓存区中。然后给这个输出增加文件下载的header头。web访问的时候,就会下载这个文件:
header(‘Content-type: application/octet-stream’); //二进制流数据(如常见的文件下载)

<?php
//访问这个文件就会进行下载
header('Content-type: application/octet-stream');
$output = fopen("php://output", "w");  
fwrite($output, "测试文本");
fclose($output);

使用浏览器访问的时候,浏览器看到http response headers 中返回的是文件下载的header头,就会调用浏览器的下载方式进行下载。
但是jQuery的ajax回调会把response的数以字符串的方式解析,所以不会调用浏览器的下载

ajax请求中不能导出Excel

JQuery的ajax函数的返回类型只有xml、text、json、html等类型,没有“流”类型,所以我们要实现ajax下载,不能够使用相应的ajax函数进行文件下载。

发起ajax请求后,当前程序只能等待返回值。如果请求地址中有header跳转或者下载文件等行为,虽然程序已经触发了,比如header的地址请求了一次,文件下载的操作也触发了。但是我们并没有看到效果。打开开发者工具,可以看到这些请求都是200的状态。但是header和文件下载。需要浏览器去执行。后端代码中是不能直接调用浏览器方法的

a链接的下载,是代码和浏览器打交道。
PHP 使用header(‘Content-type: application/octet-stream’); 返回的header头中,浏览器解析的时候知道是下载文件,也会触发下载。
ajax 请求URL,是js和服务端代码打交道。服务端代码并不能直接和浏览器打交道。所以header和文件下载就不能通过浏览器的形式表示出来。ajax返回之后,success中或者error中的header,alert等是由浏览器解析的。

ajax的本质是XMLHttpRequest对象(XHR)。XHR为向服务器发送请求和解析服务器响应提供了接口。能够以异步方式从服务器获取新数据。可以创建请求,发送请求,获取响应。类似PHP中使用curl请求,或者终端中请求接口。

终端中请求URL,也不会调用浏览器的行为和解析js代码。

测试

请求demo.html的时候,界面上弹出1,说明请求之后成功了,但是并没有执行浏览器的下。直接访问a.php的时候会直接下载文件。打开开发者工具,可以看到,虽然ajax请求没有执行浏览器的下载,但是请求是成功的。
image.png

demo.html
<html>
<head>
    <meta charset='utf-8'>
    <title>标题</title>
    <!-- js -->
    <script type="text/javascript" src="./jquery.min.js"></script>
</head>
<body>
    <button onclick="abc();">chufa</button>
</body>
</html>
<script type="text/javascript">
    function abc(){
        $.ajax({
            url:"./a.php",
            success:function(result){
                alert(1)
            }
        });
    }
</script>

a.php
<?php
header('Content-type: application/octet-stream');
$output = fopen("php://output", "w");  
fwrite($output, "测试文本");
fclose($output);

发起ajax请求后,后端执行完成之后,可以返回值。值的类型只能是字符串的形式。
image.png

如果是get的方式,直接使用js 的 window.local.href,将参数拼接到URL后面,请求的时候直接下载就行。

如果post方式传递参数,使用js 提交form表单,或者用js生成一个form,用这个form提交参数,并返回“流”类型的数据。

如果是先生成文件的下载,通过参数请求之后,这个文件已经生成了。有URL。那么可以通过ajax pose方式提交参数到后端,后端通过参数生成文件,ajax success中不能直接进行下载,但是可以返回文件的URL。success中拼接a 链接 ,并自动点击,实现下载。或者调用 window.location.href

使用js跳转函数,将表单内容拼接在后面

<button type="button" id="btnExcel" class="btn btn-success btn-xs" onclick="btnExcel_Click();"> 导出Excel</button>

//导出Excel
function btnExcel_Click(){
  window.location.href ="{{URL('/TestDrive/Crdealers/export')}}?carShop="+$("#carShop").val()+"&username="+$("#username").val();
}
<?php
//导出
public function export(Request $request){
    $model = new CarDealerSearchModel();

    foreach ($request->all() as $key => $value) {
        $model->$key = trim($value);
    }

    $arrQuery1=[['经销商名','注册账号','注册姓名','经销商手机','车牌','省','市','区','地址']];

    $arrQuery2=[];
    $query = $this->ICrdealers->query($model)->get();
    foreach($query as $kev=>$value){
        $arrQuery2[]=[$value->carShop,$value->username,$value->fullName,$value->telphone,$value->licensePlate,$value->provinceName,$value->cityName,$value->countryName,$value->address];
    }

    //$arrQuery2 = json_decode(json_encode($query), true);

    $data = array_merge($arrQuery1,$arrQuery2);

    Excel::create('经销同盟',function($excel) use ($data){

        $excel->sheet('经销同盟表', function($sheet) use ($data){
            //$sheet->setFontFamily('Comic Sans MS');//字体
            //宽度
            $sheet->setWidth(array(
                'A'     =>  15,
                'B'     =>  15,
                'C'     =>  15,
                'D'     =>  15,
                'E'     =>  15,
                'F'     =>  15,
                'G'     =>  15,
                'H'     =>  15,
                'I'     =>  30,
            ));

            $sheet->cells('A:H', function($cells) {
                $cells->setAlignment('center');//水平对齐
                //$cells->setValignment('center');//垂直对齐
            });
            $sheet->cell('I', function($cell) {
                $cell->setAlignment('left');
            });

            $sheet->cells('A1:I1', function($cells) {
                // Set font size
                //$cells->setFontSize(16);
                // Set font weight to bold
                $cells->setFontWeight('bold');
                $cells->setBackground('#D1E9F5');

            });

            //$sheet->rows($data);
          $sheet->rows($data)->freezeFirstRow();//冻结第一行(滚动的时候,第一行固定位置)

        });
    })->export('xlsx');

}