samuelterra22/laravel-report-generator

在 Laravel 6 上快速生成简单的 PDF & Excel 报告(使用 Barryvdh/DomPdf 或 Barryvdh/laravel-snappy & maatwebsite/excel)

v5.2 2020-04-10 17:22 UTC

This package is auto-updated.

Last update: 2024-09-04 09:46:00 UTC


README

本包受 Jimmy-JS 的包的启发。感谢 Jimmy-JS。

在 Laravel 上快速生成简单的 PDF 报告(使用 barryvdh/laravel-dompdfbarryvdh/laravel-snappy)或 Excel 报告(使用 Maatwebsite/Laravel-Excel

此包提供简单的 PDF & Excel 报告生成器,以加快您的工作流程

安装

将包添加到您的 composer

composer require samuelterra22/laravel-report-generator

然后,将 ServiceProvider 添加到 config/app.php 中的 providers 数组

SamuelTerra22\ReportGenerator\ServiceProvider::class,

可选,您可以将此添加到 config/app.php 中的 aliases 数组

'PdfReport'     => SamuelTerra22\ReportGenerator\Facades\PdfReportFacade::class,
'ExcelReport'   => SamuelTerra22\ReportGenerator\Facades\ExcelReportFacade::class,
'CSVReport'     => SamuelTerra22\ReportGenerator\Facades\CSVReportFacade::class,

用法

此包使用 chunk 方法(Eloquent / Query Builder),因此它可以处理大数据而不会耗尽内存。

您还可以使用 PdfReportExcelReportCSVReport 门面,这些门面已经注册为别名,以缩短代码。

示例显示 PDF 代码

// PdfReport Aliases
use PdfReport;

public function displayReport(Request $request)
{
    // Retrieve any filters
    $fromDate = $request->input('from_date');
    $toDate = $request->input('to_date');
    $sortBy = $request->input('sort_by');

    // Report title
    $title = 'Registered User Report';

    // For displaying filters description on header
    $meta = [
        'Registered on' => $fromDate . ' To ' . $toDate,
        'Sort By'       => $sortBy
    ];

    // Do some querying..
    $queryBuilder = User::select([
        'name',
        'balance',
        'registered_at'
    ])
        ->whereBetween('registered_at', [
            $fromDate,
            $toDate
        ])
        ->orderBy($sortBy);

    // Set Column to be displayed
    $columns = [
        'Name' => 'name',
        'Registered At',
        // if no column_name specified, this will automatically seach for snake_case of column name (will be registered_at) column from query result
        'Total Balance' => 'balance',
        'Status' => function ($result) { // You can do if statement or any action do you want inside this closure
            return ($result->balance > 100000) ? 'Rich Man' : 'Normal Guy';
        }
    ];

    /*
        Generate Report with flexibility to manipulate column class even manipulate column value (using Carbon, etc).

        - of()         : Init the title, meta (filters description to show), query, column (to be shown)
        - editColumn() : To Change column class or manipulate its data for displaying to report
        - editColumns(): Mass edit column
        - showTotal()  : Used to sum all value on specified column on the last table (except using groupBy method). 'point' is a type for displaying total with a thousand separator
        - groupBy()    : Show total of value on specific group. Used with showTotal() enabled.
        - limit()      : Limit record to be showed
        - make()       : Will producing DomPDF / SnappyPdf instance so you could do any other DomPDF / snappyPdf method such as stream() or download()
    */
    return PdfReport::of($title, $meta, $queryBuilder, $columns)
        ->editColumn('Registered At', [
            'displayAs' => function ($result) {
                return $result->registered_at->format('d M Y');
            }
        ])
        ->editColumn('Total Balance', [
            'displayAs' => function ($result) {
                return thousandSeparator($result->balance);
            }
        ])
        ->editColumns([
            'Total Balance',
            'Status'
        ], [
            'class' => 'right bold'
        ])
        ->showTotal([
            'Total Balance' => 'point'
            // if you want to show dollar sign ($) then use 'Total Balance' => '$'
        ])
        ->limit(20)
        ->stream(); // or download('filename here..') to download pdf
}

注意:要下载到 Excel,只需将 PdfReport 门面更改为 ExcelReport 门面,无需更多修改

数据处理

$columns = [
    'Name' => 'name',
    'Registered At' => 'registered_at',
    'Total Balance' => 'balance',
    'Status' => function($result) { // You can do data manipulation, if statement or any action do you want inside this closure
        return ($result->balance > 100000) ? 'Rich Man' : 'Normal Guy';
    }
];

将产生与以下相同的结果

$columns = [
    'Name' => function($result) {
        return $result->name;
    },
    'Registered At' => function($result) {
        return $result->registered_at;
    },
    'Total Balance' => function($result) {
        return $result->balance;
    },
    'Status' => function($result) { // You can do if statement or any action do you want inside this closure
        return ($result->balance > 100000) ? 'Rich Man' : 'Normal Guy';
    }
];

因此,您可以执行一些 预加载关系,例如

$post = Post::with('comment')->where('active', 1);

$columns = [
    'Post Title' => function($result) {
        return $result->title;
    },
    'Slug' => 'slug',
    'Top Comment' => function($result) {
        return $result->comment->body;
    }
];

输出报告

Output Report with Total

具有 Group By 的示例代码

或者,您可以使用 groupBy 方法对每组记录进行总计

    // ...
    // Do some querying..
    $queryBuilder = User::select(['name', 'balance', 'registered_at'])
                        ->whereBetween('registered_at', [$fromDate, $toDate])
                        ->orderBy('registered_at', 'ASC'); // You should sort groupBy column to use groupBy() Method

    // Set Column to be displayed
    $columns = [
        'Registered At' => 'registered_at',
        'Name' => 'name',
        'Total Balance' => 'balance',
        'Status' => function($result) { // You can do if statement or any action do you want inside this closure
            return ($result->balance > 100000) ? 'Rich Man' : 'Normal Guy';
        }
    ];

    return PdfReport::of($title, $meta, $queryBuilder, $columns)
        ->editColumn('Registered At', [
            'displayAs' => function ($result) {
                return $result->registered_at->format('d M Y');
            }
        ])
        ->editColumn('Total Balance', [
            'class'     => 'right bold',
            'displayAs' => function ($result) {
                return thousandSeparator($result->balance);
            }
        ])
        ->editColumn('Status', [
            'class' => 'right bold',
        ])
        ->groupBy('Registered At')
        ->showTotal([
            'Total Balance' => 'point'
        ])
        ->stream();

请务必注意,为了使用此 Group By 方法,请先通过查询对 Group By 列进行排序。

按注册时间输出具有 Group By 的报告

Output Report with Group By Total

其他方法

1. setPaper($paper = 'a4')

支持媒体类型:PDF

描述:设置纸张大小

参数:

  • $paper (默认:'a4')

用法

PdfReport::of($title, $meta, $queryBuilder, $columns)
         ->setPaper('a6')
         ->make();

2. setCss(Array $styles)

支持媒体类型:PDF、Excel

描述:使用给定的选择器和样式设置新的自定义样式

参数:

  • Array $styles (键:$selector,值:$style)

用法

ExcelReport::of($title, $meta, $queryBuilder, $columns)
    ->editColumn('Registered At', [
        'class' => 'right bolder italic-red'
    ])
    ->setCss([
        '.bolder'     => 'font-weight: 800;',
        '.italic-red' => 'color: red;font-style: italic;'
    ])
    ->make();

3. setOrientation($orientation = 'portrait')

支持媒体类型:PDF

描述:设置方向为横幅或肖像

参数:

  • $orientation (默认:'portrait')

用法

PdfReport::of($title, $meta, $queryBuilder, $columns)
         ->setOrientation('landscape')
         ->make();

4. withoutManipulation()

支持媒体类型:PDF、Excel、CSV

描述:快速生成报告,但所有列属性必须与从 SQL 查询中选择的列匹配

用法

$queryBuilder = Customer::select(['name', 'age'])->get();
$columns = ['Name', 'Age'];
PdfReport::of($title, $meta, $queryBuilder, $columns)
         ->withoutManipulation()
         ->make();

5. showMeta($value = true)

支持媒体类型:PDF、Excel、CSV

描述:在报告中显示/隐藏元属性

参数:

  • $value (默认:true)

用法

PdfReport::of($title, $meta, $queryBuilder, $columns)
         ->showMeta(false) // Hide meta
         ->make();

6. showHeader($value = true)

支持媒体类型:PDF、Excel、CSV

描述:在报告中显示/隐藏列标题

参数:

  • $value (默认:true)

用法

PdfReport::of($title, $meta, $queryBuilder, $columns)
         ->showHeader(false) // Hide column header
         ->make();