首页 > 解决方案 > 如何在 OctoberCms 上直接导出文件

问题描述

我创建了一个看起来像这样的自定义页面,因此所有功能都是自定义的。我想知道如何使用我的导出按钮直接导出我的表上显示的结果,而不必在导出页面上重定向,因为默认功能会将您重定向到某个页面,这也是我为了检索而避免的过滤它并将其应用于导出功能。

我创建了一个调用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 很陌生。

标签: octobercms

解决方案


最好的解决方案是将您添加own controller actionexport data.

主要参考:https ://tutorialmeta.com/october-cms/october-cms-export-csv

在工具栏中添加一个新按钮,该按钮将指向您的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链接。

控制器端。

<?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 文件中。

现在,当您单击Export按钮时,它将让您下载export.csv文件。其内容如下。

在此处输入图像描述

如有任何疑问,请发表评论。


推荐阅读