【问题标题】:How to export file directly on OctoberCms如何在 OctoberCms 上直接导出文件
【发布时间】:2021-06-16 10:27:47
【问题描述】:

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

我创建了一个调用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 的新手。

【问题讨论】:

  • 如果有帮助请检查这个答案:stackoverflow.com/questions/49710918/…
  • @HardikSatasiya 提到使用 columns.yaml 另一个是我没有这个,因为我的报告模型/控制器正在调用其他模型,因为我希望我的报告包含其他模型的所有导出功能
  • 我不确定我是否能够使用useList: true,因为我已经在我的页面@HardikSatasiya 创建了一个自定义表格。我已经更新了代码,所以你可以检查
  • ok np 一旦我有空会分享手动的方法,我们自己的数据使用循环遍历它们

标签: octobercms


【解决方案1】:

最好的解决方案是将您的own controller action 添加到export 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>

注意:请根据您的需要替换网址中的author name/plugin namecontroller 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 文件。 其内容如下。

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

【讨论】:

  • 抱歉回复晚了。我会研究并尝试在我的本地实现这一点。
  • 非常感谢您的详细解释。这是一个非常自定义的代码,文档中甚至都没有提到。非常感谢您为添加解释所做的努力。
  • 我希望这对你有用,现在你可以自己导出东西了吗? ?
猜你喜欢
  • 2017-11-08
  • 1970-01-01
  • 2018-02-05
  • 2017-10-20
  • 2016-01-05
  • 1970-01-01
  • 2018-03-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多