如何在 OctoberCms 上直接导出文件
How to export file directly on OctoberCms
我创建了一个看起来像这样的自定义页面,因此所有功能都是自定义的。我想知道如何使用导出按钮直接导出 table 上显示的结果,而不必在导出页面上重定向,因为默认功能会将您重定向到特定页面,而这正是我要避免的还检索过滤器并将其应用于导出功能。
我创建了一个调用 exportOrders
它在控制器上还没有任何功能,因为我不知道如何处理它。
控制器.htm
<?= Form::open(['class' => 'layout']) ?>
<div class="filter-container">
<div class="row">
<div class="status-container column">
<label for="status">Status:</label>
<select id="statusFilter" class="form-control custom-select" name="status">
<option value="none" selected>None</option>
<option value="processing">Processing</option>
</select>
</div>
(...)
</div>
<button>
(...)
</button>
<button
id="exportOrders"
type="submit"
data-request="onExportOrders"
data-hotkey="ctrl+s, cmd+s"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
class="btn btn-secondary">
Export
</button>
</div>
<div class="orders-table">
<table class="table d-flex justify-content-center">
<thead>
<th>Order ID</th>
<th>Product Name</th>
<th>Status</th>
<th>Payment Method</th>
<th>SKU</th>
<th>Total</th>
</thead>
<tbody>
<?php foreach($orders as $data) {
# declare variables here
$id = $data['id'];
$status = $data['status'];
$payment_gateway = $data['payment_gateway'];
$total = $data['total'];
$sku = $data['sku'];
$product_name = $data['product_name'];
echo("<tr>
<td><a target='' href='/admin/xtendly/ecommerce/orders/update/$data[id]'>$id</a></td>
<td>$product_name</td>
<td>$status</td>
<td>$payment_gateway</td>
<td>$total</td>
<td>$sku</td>
</tr>");
} ?>
</tbody>
</table>
</div>
<?= Form::close() ?>
这是我处理结果的控制器
public $implement = [
'Backend\Behaviors\ListController',
'Backend\Behaviors\FormController',
'Backend\Behaviors\ReorderController'
];
public $listConfig = 'config_list.yaml';
public $formConfig = 'config_form.yaml';
public $reorderConfig = 'config_reorder.yaml';
public function __construct()
{
parent::__construct();
BackendMenu::setContext('X.Ecommerce', 'main-menu-item2');
}
public function partialRenderOrders()
{
$status = post('status');
$payment = post('payment');
$data = $this->getOrders($status, $payment);
$params = [
'orders' => $data,
];
return $this->makePartial('orders', $params);
}
public function getOrders($status_ = null) {
$query = Order::query();
if($status_ !== "none" || $status_ == null) {
$result = $query->where('status','LIKE','%'.$status_.'%')->get();
} else {
$result = $query->get();
}
$collection = collect($result->toArray());
$data = $collection->map(function ($item) {
if(is_array($item)) {
foreach($item as $key => $value) {
//Order Details
if($key == 'order_details') {
$order_details = json_decode($value);
$sku_ = ""; $product_name = "";
$last = count($order_details) - 1;
for($i = 0; $i < count($order_details); $i++) {
if($last > $i) {
//sku
$sku_.= isset($order_details[$i]->sku) && $order_details[$i]->sku !== "" ? "".strval($order_details[$i]->sku).", " : '';
//product name
$product_name = isset($order_details[$i]->title) && $order_details[$i]->title !== "" ? "".strval($order_details[$i]->title).", " : '';
} else {
//sku
$sku_.= isset($order_details[$i]->sku) && $order_details[$i]->sku !== "" ? "".strval($order_details[$i]->sku)."" : '';
//product name
$product_name.= isset($order_details[$i]->title) && $order_details[$i]->title !== "" ? "".strval($order_details[$i]->title)."" : '';
}
}
$item['sku'] = $sku_;
$item['product_name'] = $product_name;
}
}
}
return $item;
});
return $data;
}
如果你能提供一个好的代码,那将是一个很大的帮助,因为我对 OctoberCMS 还很陌生。
最好的解决方案是将 own controller action
添加到 export data
。
Main Ref: https://tutorialmeta.com/october-cms/october-cms-export-csv
In toolbar add a new button which will point to your controller's action
<button
onclick="{
const status = 'active';// use selector to get value $('#statusFilter').val();
window.location = `<?= Backend::url('hardik/sotest/items/export') ?>/${status}`;
}"
class="btn btn-primary oc-icon-sign-out">
Export
</button>
注意:请根据您的需要替换URL中的author name/plugin name
和controller name
。
如果您不需要传递任何过滤器值,您可以直接使用 a href
link.
Controller side.
<?php
//..some code
use League\Csv\Writer as CsvWriter;
use October\Rain\Parse\League\EscapeFormula as CsvEscapeFormula;
class Items extends Controller
{
//.. some code
// CUSTOM CSV EXPORT logic
// only write $status param if you intend to pass it for filter
public function export($status)
{
// dd($status); -> O/P => active
// $status will have value which was passed while calling URL as param
// now use this to filter your data
// you can add as many params you need
// file name when you download CSV
$fileName = 'export.csv';
// prepare CSV writer
$csv = CsvWriter::createFromFileObject(new \SplTempFileObject);
$csv->setOutputBOM(CsvWriter::BOM_UTF8);
$formatter = new CsvEscapeFormula();
// add headers as per your need
$csv->insertOne(['Name', 'Flower']);
// add records
// here I added some demo data you need to fetch from DB or something
// probabally use $results = $this->getOrders($status); here
$results = [
[
'name' => 'First Name',
'flower' => 'Rose'
],
[
'name' => 'Second Name',
'flower' => 'Lavender'
],
];
// loop through your records and add to csv rows
foreach ($results as $result) {
// formate data and escape quotes etc
$data = $formatter($result);
// add single record to CSV
$csv->insertOne([
$data['name'], // this will be name
$data['flower'] // this will be flower
]);
}
// Save for download
$csvName = uniqid('hs');
$csvPath = temp_path().'/'.$csvName;
$output = $csv->__toString();
\File::put($csvPath, $output);
// download it
return \Response::download($csvPath, $fileName)->deleteFileAfterSend(true);
}
}
注意: 在此示例中,我添加了用于通用目的的演示数据,您可以替换它并使用您自己的数据源并循环遍历它们并将它们添加到 CSV 文件中。
Now when you click on the Export
button it will let you download the export.csv
file.
and its content will be as below.
如有疑问请评论。
我创建了一个看起来像这样的自定义页面,因此所有功能都是自定义的。我想知道如何使用导出按钮直接导出 table 上显示的结果,而不必在导出页面上重定向,因为默认功能会将您重定向到特定页面,而这正是我要避免的还检索过滤器并将其应用于导出功能。
我创建了一个调用 exportOrders
它在控制器上还没有任何功能,因为我不知道如何处理它。
控制器.htm
<?= Form::open(['class' => 'layout']) ?>
<div class="filter-container">
<div class="row">
<div class="status-container column">
<label for="status">Status:</label>
<select id="statusFilter" class="form-control custom-select" name="status">
<option value="none" selected>None</option>
<option value="processing">Processing</option>
</select>
</div>
(...)
</div>
<button>
(...)
</button>
<button
id="exportOrders"
type="submit"
data-request="onExportOrders"
data-hotkey="ctrl+s, cmd+s"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
class="btn btn-secondary">
Export
</button>
</div>
<div class="orders-table">
<table class="table d-flex justify-content-center">
<thead>
<th>Order ID</th>
<th>Product Name</th>
<th>Status</th>
<th>Payment Method</th>
<th>SKU</th>
<th>Total</th>
</thead>
<tbody>
<?php foreach($orders as $data) {
# declare variables here
$id = $data['id'];
$status = $data['status'];
$payment_gateway = $data['payment_gateway'];
$total = $data['total'];
$sku = $data['sku'];
$product_name = $data['product_name'];
echo("<tr>
<td><a target='' href='/admin/xtendly/ecommerce/orders/update/$data[id]'>$id</a></td>
<td>$product_name</td>
<td>$status</td>
<td>$payment_gateway</td>
<td>$total</td>
<td>$sku</td>
</tr>");
} ?>
</tbody>
</table>
</div>
<?= Form::close() ?>
这是我处理结果的控制器
public $implement = [
'Backend\Behaviors\ListController',
'Backend\Behaviors\FormController',
'Backend\Behaviors\ReorderController'
];
public $listConfig = 'config_list.yaml';
public $formConfig = 'config_form.yaml';
public $reorderConfig = 'config_reorder.yaml';
public function __construct()
{
parent::__construct();
BackendMenu::setContext('X.Ecommerce', 'main-menu-item2');
}
public function partialRenderOrders()
{
$status = post('status');
$payment = post('payment');
$data = $this->getOrders($status, $payment);
$params = [
'orders' => $data,
];
return $this->makePartial('orders', $params);
}
public function getOrders($status_ = null) {
$query = Order::query();
if($status_ !== "none" || $status_ == null) {
$result = $query->where('status','LIKE','%'.$status_.'%')->get();
} else {
$result = $query->get();
}
$collection = collect($result->toArray());
$data = $collection->map(function ($item) {
if(is_array($item)) {
foreach($item as $key => $value) {
//Order Details
if($key == 'order_details') {
$order_details = json_decode($value);
$sku_ = ""; $product_name = "";
$last = count($order_details) - 1;
for($i = 0; $i < count($order_details); $i++) {
if($last > $i) {
//sku
$sku_.= isset($order_details[$i]->sku) && $order_details[$i]->sku !== "" ? "".strval($order_details[$i]->sku).", " : '';
//product name
$product_name = isset($order_details[$i]->title) && $order_details[$i]->title !== "" ? "".strval($order_details[$i]->title).", " : '';
} else {
//sku
$sku_.= isset($order_details[$i]->sku) && $order_details[$i]->sku !== "" ? "".strval($order_details[$i]->sku)."" : '';
//product name
$product_name.= isset($order_details[$i]->title) && $order_details[$i]->title !== "" ? "".strval($order_details[$i]->title)."" : '';
}
}
$item['sku'] = $sku_;
$item['product_name'] = $product_name;
}
}
}
return $item;
});
return $data;
}
如果你能提供一个好的代码,那将是一个很大的帮助,因为我对 OctoberCMS 还很陌生。
最好的解决方案是将 own controller action
添加到 export data
。
Main Ref: https://tutorialmeta.com/october-cms/october-cms-export-csv
In toolbar add a new button which will point to your
controller's action
<button
onclick="{
const status = 'active';// use selector to get value $('#statusFilter').val();
window.location = `<?= Backend::url('hardik/sotest/items/export') ?>/${status}`;
}"
class="btn btn-primary oc-icon-sign-out">
Export
</button>
注意:请根据您的需要替换URL中的author name/plugin name
和controller name
。
如果您不需要传递任何过滤器值,您可以直接使用 a href
link.
Controller side.
<?php
//..some code
use League\Csv\Writer as CsvWriter;
use October\Rain\Parse\League\EscapeFormula as CsvEscapeFormula;
class Items extends Controller
{
//.. some code
// CUSTOM CSV EXPORT logic
// only write $status param if you intend to pass it for filter
public function export($status)
{
// dd($status); -> O/P => active
// $status will have value which was passed while calling URL as param
// now use this to filter your data
// you can add as many params you need
// file name when you download CSV
$fileName = 'export.csv';
// prepare CSV writer
$csv = CsvWriter::createFromFileObject(new \SplTempFileObject);
$csv->setOutputBOM(CsvWriter::BOM_UTF8);
$formatter = new CsvEscapeFormula();
// add headers as per your need
$csv->insertOne(['Name', 'Flower']);
// add records
// here I added some demo data you need to fetch from DB or something
// probabally use $results = $this->getOrders($status); here
$results = [
[
'name' => 'First Name',
'flower' => 'Rose'
],
[
'name' => 'Second Name',
'flower' => 'Lavender'
],
];
// loop through your records and add to csv rows
foreach ($results as $result) {
// formate data and escape quotes etc
$data = $formatter($result);
// add single record to CSV
$csv->insertOne([
$data['name'], // this will be name
$data['flower'] // this will be flower
]);
}
// Save for download
$csvName = uniqid('hs');
$csvPath = temp_path().'/'.$csvName;
$output = $csv->__toString();
\File::put($csvPath, $output);
// download it
return \Response::download($csvPath, $fileName)->deleteFileAfterSend(true);
}
}
注意: 在此示例中,我添加了用于通用目的的演示数据,您可以替换它并使用您自己的数据源并循环遍历它们并将它们添加到 CSV 文件中。
Now when you click on the
Export
button it will let you download theexport.csv
file. and its content will be as below.
如有疑问请评论。