【发布时间】:2018-12-27 02:48:39
【问题描述】:
我的任务是将 100,000 行记录从我的数据库导出为 csv 格式。
执行此操作的最佳方法是什么?我完全不知道要搜索和研究什么。
我想在下载尚未完成时像其他网站一样使用 PART 格式进行块下载,同时不要让我的服务器耗尽。
我该怎么做?
谢谢!
【问题讨论】:
-
我一定会看的谢谢!
我的任务是将 100,000 行记录从我的数据库导出为 csv 格式。
执行此操作的最佳方法是什么?我完全不知道要搜索和研究什么。
我想在下载尚未完成时像其他网站一样使用 PART 格式进行块下载,同时不要让我的服务器耗尽。
我该怎么做?
谢谢!
【问题讨论】:
您可以将 Symfony HttpFoundation 组件中的 StreamedResponse 与 Doctrine iterate 结合使用。
类似这样的:
$response = new StreamedResponse(function () {
$data = $this->myQuery()->iterate();
$csv = fopen('php://output', 'w+');
while (false !== ($line = $data->next())) {
fputcsv($csv, [$line[0]->column1], ';');
}
fclose($csv);
});
$response->headers->set('Content-Type', 'text/csv; charset=utf-8');
$response->headers->set('Content-Disposition', 'attachment; filename="file.csv"');
【讨论】:
while 循环中使用if (isset($line[0]))
你可以这样做:
控制器功能:
private function downloadCSV(QueryBuilder $query): Response
{
$csv = $this->renderView('templates/csv/template.csv.twig', [
'data' => $query->getQuery()->getResult(),
]);
// crafting response
$response = new Response($csv);
$disposition = $response->headers->makeDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
sprintf('file_%s.csv', time()));
$response->headers->set('Content-Type', 'text/csv');
$response->headers->set('Content-Disposition', $disposition);
return $response;
}
在模板中渲染 CSV:
{% set header = [
'Internal Id',
'title',
'url'
] %}
{{ str_putcsv(header) }}
{% for i in data %}
{% spaceless %}
{% set row = [
i.id,
i.title,
absolute_url(path('route_to_post', { data: i.id }))
] %}
{% endspaceless %}
{{ str_putcsv(row) }}
{% endfor %}
【讨论】:
str_putcsv 函数的作用吗?