symball / report
这个包提供了一套工具,旨在加速使用Symfony创建Excel风格报告的过程,而不强迫您以某种特定方式行事。功能包括:
Requires
- php: >=5.3.2
- phpoffice/phpexcel: ~1.8.1
- symfony/symfony: ~2.6|~3.0
This package is not auto-updated.
Last update: 2024-09-29 03:47:04 UTC
README
这个包提供了一套工具,旨在加速使用Symfony创建Excel风格报告的过程,而不强迫您以某种特定方式行事。功能包括:
- 一个用于将内容写入PHPExcel的抽象层,支持多工作表
- 一个用于指针移动和多个对象/集跟踪的导航处理服务
- 一个数据代理,作为渲染前数据准备的单一点
- 一个数据库查询处理器,用于定义信息检索
- 一个模式服务,允许一次编写,多次重用常见报告功能
- 一个样式服务,用于向电子表格添加展示,如不同的字体样式、背景、边框等
- 将报告输出到PHPExcel支持的所有格式,返回一个可以进一步操作的Symfony文件对象。例如,使用Gaufrette上传到Amazon S3
这个包是由于一个需要创建许多报告的项目而产生的,目前还没有足够的包来满足这个需求。而不是选择重复相同的代码,我创建了一个带有一些简单实用函数的包装器,在我意识到之前,它已经足够灵活,可以支持报告的各种功能,因此我得到了一个包。
安装
使用Composer要求该包
composer require symball/report
在您的Kernel空间内启用该包
public function registerBundles() { $bundles = [ // ... new Symball\ReportBundle\SymballReportBundle(), // ... ]; ... }
在您的配置中设置报告的保存路径
symball_report: default_report_path: "%kernel.root_dir%/../var/reports"
使用
此包提供的服务集合可以独立使用,但为了充分利用它,您应使用容器中提供的名称为的门面服务
$reportBuilder = $container->get('symball_report.report_builder');
由于报告可能需要处理大量数据,建议在Symfony命令中定义您的报告,以确保请求不会超时。
报告布局
通过meta函数访问数据代理服务。此服务负责设置高级选项和跟踪
$reportBuilder->meta()
选项
您将在报告中使用的任何“选项”都由meta服务处理,并可供其他服务使用,或者在使用模式或样式服务的情况下,自动包含。有关标准分布中使用的某些选项的信息,请参阅选项部分
$reportBuilder->meta() // Set a single option. ->setOption('option_key', false) // Set multiple options from array ->setOptions(['option_key' => 'option_value',]) // Retrieve the value of a single option ->getOption('option_key') // Retrieve all options ->getOptions()
列定义
按照参数定义的顺序
- 内部引用,用于设置/访问数据。对于展示,如果在选项参数中没有设置标题,则下划线被替换为空格,单词被大写。
- 可选 默认列值。如果为空,则值为空字符串。
- 可选 列选项数组。
// String column ->column('column_reference') // Numeric column ->column('column_reference', 0) // String column With custom default value ->column('column_reference', 'NA') // Custom column heading ->column('column_reference', 'NA', ['title' => 'My custom heading'] // Setting some display options which will be parsed at render time ->column('column_reference', 0, ['display_options' => ['highlight_negative']])
数据收集
查询定义
**注意** - 此功能目前相当基础,将进行升级。
查询服务提供了一种定义用于报告的原始数据收集的方法。目标是创建多种报告在多个数据集上如何工作的模型,例如基于时间间隔的报告。
此服务的第一种形式(其他服务将从其继承并添加方法)目前按以下方式运行
// Create the query object you will use $query = new Query(); $query->setRepository($aDoctrineRepository) // Inform the query object that the report will span multiple data sets. 1 by default $query->setNumberDataSets(3) // Optionally define a base query (currently Doctrine Query Builder) to be present across all data sets // If not used, will try to fetch all $query->setQueryBase($doctrine->createQueryBuilder()->field('status')->equals('active')); // When using multiple data sets, refine search parameters across the sets. Used within the "set loop" $query->addModifier('database_field', ['type' => 'equals', 'value' => 'example_value']);
此外,还有一种查询类型,旨在处理涉及时间范围的报告,它扩展了上面定义的基本查询服务,并增加了一些方法和行为。
// Create the query object you will use $query = new QueryTimeInterval(); // When to start $query->setHeadDateTime(new \DateTime()); // Time that each set will span $query->setIntervalDateTime(new \DateInterval('P1W'));
数据处理
集合循环
为了使报告中的数据有意义,通常需要进行某种形式的数据处理。集合循环提供了
- 使用最小代码处理多个数据集
- 跟踪数据点(x轴)位置的地方,无需考虑新点可能的位置
- 值将根据列定义重置。
// If only using a single set $reportBuilder->newSet(); $unprocessedData = $reportBuilder->query()->run(); // For handling multiple sets while($reportBuilder->newSet()) { $unprocessedData = $reportBuilder->query()->run(); }
使用上述代码,您可能会注意到数据只设置到名为unprocessedData的变量中;这是一个Doctrine集合,您可以遍历。要使报告生成器识别数据,需要使用数据代理,它提供了一些使事情变得简单的实用工具
foreach($unprocessedData as $dataElement) { // Determine whether this element is overdue or not $aProcessedValue = ($dataElement->getValue() > 70) ? 'pass' : 'fail'; $reportBuilder->meta() // Set a point of reference where data will be stored. Internally, this is stored as a string so if you pass an // object, it will try stringify it ->setPoint($dataElement) // Set the value of a column ->set('column_reference', $dataElement->getValue()) // Use the processed value ->set('column_reference', $aProcessedValue) // Increment the value of a column by 1 ->increment('column_reference') // Increment the value of a column by custom amount ->increment('column_reference', $dataElement->getValue()) }
您可能正在创建一个将数据分组在一起的报告,例如按分支机构划分的销售。这就是为什么存在setPoint和increment,它们为您提供修改现有条目的方法。
当数据点尚未定义时,它们将被添加到数据代理中,并随后进行跟踪。如果您(例如)在100个集合之后添加新数据点,它们将简单地显示在末尾,不会影响任何先前集合的位置。
** 注意 ** - 可以使用$meta->addPoint('reference');
手动定义数据点。
简单渲染
虽然报告生成器提供了辅助工具来帮助用内容填充电子表格,但有一个模式服务,它将预定义的常见功能的流程包装成一行。模式是带有标签的服务,它将报告生成器作为参数。
$reportPattern = $container->get('symball_report.pattern'); // Get a simple array list of available patterns $availablePatterns = $reportPattern->getPatternsLoaded(); // Draw column headings for the current data set $reportPattern->run('set_headings', $reportBuilder); // Fill in the data set values $reportPattern->run('data_set', $reportBuilder); // Draw the data point index (x axis) $reportPattern->run('data_point_index', $reportBuilder);
创建新模式
如果您打算创建新的渲染模式,它需要是一个带标签的服务并实现模式接口。
use Symball\ReportBundle\Service\ReportBuilder; use Symball\ReportBundle\Interfaces\Pattern; class YourPattern implements Pattern { public function run(ReportBuilder &$context) { // Do something with the report builder } }
# In your services configuration report_pattern.data_point_index: class: AppBundle\ReportPatterns\YourPatter tags: - { name: symball_report.pattern, alias: your_pattern_reference
模式定义后,只需在创建报告时使用您的别名即可。以下是一个示例
$reportPattern->run('your_pattern_reference', $reportBuilder);
手动控制
如果您计划手动填充电子表格,建议您查看一些现有的模式,以了解事情是如何联系在一起的。有三个类为您提供了填充电子表格的各种功能
ReportBuilder
主要的报告生成器服务本身有一个将内容写入当前导航指针所在单元格的函数
// Write a value $reportBuilder->write('some_value'); // Write a formula $reportBuilder->write('=(1+1)'); // Write a custom formula // The formula writer will be redesigned $reportBuilder->formula(1+1); // Use one of the predefined formulae. This one totals up all values going up the x axis for the current column $reportBuilder->formula('sum_up_data');
导航
导航服务用于控制指针,将行和列信息抽象为数字索引,同时提供使指针跟踪人性化并防止指针执行诸如超出范围等操作的实用函数。
导航服务可以互换,如果您使用人性化语法,则可以自动调整指针在电子表格中的移动方式。这意味着您可以将数据点水平流动、垂直流动,甚至跨越多个字段而不是一个字段。默认情况下,使用数据点垂直流动和列标题水平分散的导航服务。
$nav = $reportBuilder->nav(); // BASIC CONTROLS // Display the current coordinates in spreadsheet format (string) $nav $nav->coord() // Move down 1 cell $nav->down() // Move right 5 cells ->right(5) // Move up 1 cell ->up() // Move left 5 cells ->left(5) // Move along the x axis 1 cell ->axisXMove() // Move along the y axis 5 cells ->axisYMove(5)
人性化语法
在nav服务中,当引用行、列或两者以及能够使用数字索引时,还有三个字符串值可以根据上下文返回坐标。这些是
- current 指的是指针当前的位置
- set 当在数据点或数据集中移动时,这指的是当前跟踪位置的开始。以下示例不考虑标题的空间
- 如果您有一个有2列的报告,且在第三个集合上,请求集合列将返回6。
- 如果您有一个包含100个数据点的报告,并且处于第50组,请求该组行将返回50
- 初始 指的是起始行/列,它将永远不会改变。这在跨数据集移动时很有用,此时需要将指针移到第一行
考虑到以上内容
// Change the current column set value. This is automatically called when using the *newSet* function $nav->movePointerAlong($this->meta->columnCount()) // Get the starting coordinates for the current data set $nav->coord('initial', 'set') // Move the row pointer to where the spreadsheet expects data to start $nav->rowReset('initial') // Move the column pointer to start of the current set $nav->columnReset('set');
** 注意 ** - 当提到坐标时,Excel表格将使用字母索引来表示列,例如A或AG。导航服务使用数字索引,并且在转换为字符串时将自动为您转换。在手动检索列时,如果您需要字母索引,需要将true传递给第二个参数或手动转换。
// A1 (string) $nav // Will have 1 $nav->column() $nav->column('current') // Will have A $nav->column('', true) $nav->column(false, true $nav->column('current', true) $nav->nmbToClm($nav->column())
样式
由于样式在多种上下文中使用,因此通过reportBuilder服务本身访问样式服务。但从设计和操作的角度来看,它类似于模式构建器。您在元服务中定义的任何选项都会在调用函数时传递给样式服务(以获得一组良好的默认值),但可以使用第三个参数进行覆盖和扩展。
由于样式的性质(可以使用范围),需要传递一个坐标字符串作为第二个参数。
// Apply a background (using the default background colour) to current location $reportBuilder->style('bg', (string) $reportBuilder->nav()); // Apply a background using a custom colour $reportBuilder->style('bg', (string) $reportBuilder->nav(), ['color' => 'B0171F']); $start = $nav->coord('initial', 'current'); // Note the column value manipulation $end = $nav->coord(($nav->column() - 1), 'current'); // Draw a border along a range $reportBuilder->style('border', (string) $reportBuilder->nav(), ['color' => 'B0171F']);
保存报告
Excel服务有一个快捷方式,可以通过报告构建器保存电子表格。默认情况下,它将使用您配置中指定的路径和格式。
$fileObject = $reportBuilder->save('filename.xls'); // Save the report to a one off path $fileObject = $reportBuilder->save('filename.xls', '/custom/path'); // Save the report with a one off format $fileObject = $reportBuilder->save('filename.xls', '', 'Excel5');