我想将PDF导出集成到我的SONATA ADMIN应用程序中。为此,我安装了KnpSnappy Bundle和SonataExporterBundle。 我按照谷歌上发现的旧教程,但最终它不起作用。
config.yml:
knp_snappy:
pdf:
enabled: true
binary: /usr/local/bin/wkhtmltopdf
options: []
image:
enabled: true
binary: /usr/local/bin/wkhtmltoimage
options: []
temporary_folder: %kernel.cache_dir%/snappy
services.yml:
sonata.admin.exporter:
class: AppBundle\Export\Exporter
calls:
- ["setKnpSnappyPdf", ["@knp_snappy.pdf"]]
- ["setTemplateEngine", ["@templating"] ]
在我的ModelAdmin中,我添加了它:
public function getExportFormats() {
return array_merge(parent::getExportFormats(), array('pdf'));
}
我创建了AppBundle / Export / Exporter.php:
namespace AppBundle\Export;
use Exporter\Source\SourceIteratorInterface;
use Symfony\Component\HttpFoundation\Response;
use Sonata\AdminBundle\Export\Exporter as BaseExporter;
class Exporter extends BaseExporter
{
protected $knpSnappyPdf;
protected $templateEngine;
public function getResponse($format, $filename, SourceIteratorInterface $source)
{
if ('pdf' != $format) {
return parent::getResponse($format, $filename, $source);
}
$html = $this->templateEngine->renderView('AppBundle:Export:pdf.html.twig', array(
'source' => $source
));
$content = $this->knpSnappyPdf->getOutputFromHtml($html);
return new Response($content, 200, array(
'Content-Type' => 'application/pdf',
'Content-Disposition' => sprintf('attachment; filename=%s', $filename)
));
}
public function setKnpSnappyPdf($service)
{
$this->knpSnappyPdf = $service;
}
public function setTemplateEngine($service)
{
$this->templateEngine = $service;
}
}
错误:
RuntimeException:
Invalid "pdf" format, supported formats are : "csv, json, xls, xml"
at vendor/sonata-project/exporter/src/Exporter.php:52
at Exporter\Exporter->getResponse('pdf', 'export_model_2018_04_20_15_44_05.pdf', object(DoctrineORMQuerySourceIterator))
(vendor/sonata-project/admin-bundle/src/Controller/CRUDController.php:952)
at Sonata\AdminBundle\Controller\CRUDController->exportAction(object(Request))
(vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php:151)
at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
(vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php:68)
at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
(vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php:202)
at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
(web/app_dev.php:31)
at require('/var/www/html/acianovintra/web/app_dev.php')
(vendor/symfony/symfony/src/Symfony/Bundle/WebServerBundle/Resources/router.php:42)
你能告诉我我做错了吗?
答案 0 :(得分:0)
在一个项目中,我不得不以docx格式导出一些数据。
为此,我写了一个自定义作家:
<?php
namespace App\MyBundle\Utils\Exporter\Writer;
use Exporter\Writer\TypedWriterInterface;
class DocxWriter implements TypedWriterInterface
{
/**
* {@inheritdoc}
*/
final public function getDefaultMimeType()
{
return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
}
/**
* {@inheritdoc}
*/
final public function getFormat()
{
return 'docx';
}
//...
}
然后我必须为编写者创建一个服务并添加一个标记:
// service.xml
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="app.exporter.writer.docx" class="App\MyBundle\Utils\Exporter\Writer\DocxWriter">
<argument>php://output</argument>
<tag name="sonata.exporter.writer"/>
</service>
</services>
</container>
在导出程序包的ExporterCompilerPass
中,sonata获取标有sonata.exporter.writer
的所有服务,并将其传递给addWriter
类的Exporter
。
要在sonata admin中集成这个新作家,你必须像你已经做的那样覆盖sonata.admin.exporter
,除了你会称这个新作家:
<?php
namespace App\MyBundle\Export;
use Exporter\Source\SourceIteratorInterface;
use Sonata\AdminBundle\Export\Exporter as BaseExporter;
use App\MyBundle\Utils\Exporter\Writer\DocxWriter;
use Symfony\Component\HttpFoundation\StreamedResponse;
class Exporter extends BaseExporter
{
public function getResponse($format, $filename, SourceIteratorInterface $source)
{
switch ($format) {
case 'docx':
$writer = new DocxWriter('php://output');
$contentType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
break;
default:
return parent::getResponse($format, $filename, $source);
}
$callback = function () use ($source, $writer) {
$handler = \Exporter\Handler::create($source, $writer);
$handler->export();
};
return new StreamedResponse($callback, 200, array(
'Content-Type' => $contentType,
'Content-Disposition' => sprintf('attachment; filename="%s"', $filename),
));
}
}
有了这个,你应该能够在管理员中添加你的pdf格式覆盖getExportFormats
方法。
Hpe this help