我正在生成pdf文件,但未生成文件,但是由于我做了作曲家更新(从symfony 4.2.4到4.2.5),因此出现以下错误
未创建文件'generated / pdf /Mon_Beau_Chateau_Roi_Des_Fôrets_Su-Per_04-2019_8ddb3a64c4.pdf'(命令:/ var / www / html / gestImmo / bin / wkhtml2pdf --lowquality'/tmp/knp_snappy5ca4ac7.2a32d。生成/pdf/Mon_Beau_Chateau_Roi_Des_Frets_Su-Per_04-2019_8ddb3a64c4.pdf')。
我看了日志,没有发现问题:
[2019-04-03 14:52:10] snappy.INFO: Generate from file(s) "/tmp/knp_snappy5ca4ac7a32b3d7.26041529.html" to file "generated/pdf/Mon_Beau_Chateau_Roi_Des_Fôrets_Su-Per_04-2019_8ddb3a64c4.pdf". {"command":"/var/www/html/gestImmo/bin/wkhtml2pdf --lowquality '/tmp/knp_snappy5ca4ac7a32b3d7.26041529.html' 'generated/pdf/Mon_Beau_Chateau_Roi_Des_Frets_Su-Per_04-2019_8ddb3a64c4.pdf'","env":null,"timeout":false} []
[2019-04-03 14:52:10] snappy.ERROR: An error happened while generating "generated/pdf/Mon_Beau_Chateau_Roi_Des_Fôrets_Su-Per_04-2019_8ddb3a64c4.pdf". {"command":"/var/www/html/gestImmo/bin/wkhtml2pdf --lowquality '/tmp/knp_snappy5ca4ac7a32b3d7.26041529.html' 'generated/pdf/Mon_Beau_Chateau_Roi_Des_Frets_Su-Per_04-2019_8ddb3a64c4.pdf'","status":0,"stdout":"QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-www-data'\nlibpng warning: iCCP: known incorrect sRGB profile\nlibpng warning: iCCP: known incorrect sRGB profile\nLoading page (1/2)\n[> ] 0%\r[==============================> ] 50%\rWarning: Failed to load file:///build/runtime.js (ignore) \nWarning: Failed to load file:///build/app.js (ignore)\n[============================================================] 100%\rPrinting pages (2/2) \n[> ] \rDone \n","stderr":""} []
[2019-04-03 14:52:10] request.CRITICAL: Uncaught PHP Exception RuntimeException: "The file 'generated/pdf/Mon_Beau_Chateau_Roi_Des_Fôrets_Su-Per_04-2019_8ddb3a64c4.pdf' was not created (command: /var/www/html/gestImmo/bin/wkhtml2pdf --lowquality '/tmp/knp_snappy5ca4ac7a32b3d7.26041529.html' 'generated/pdf/Mon_Beau_Chateau_Roi_Des_Frets_Su-Per_04-2019_8ddb3a64c4.pdf')." at /var/www/html/gestImmo/vendor/knplabs/knp-snappy/src/Knp/Snappy/AbstractGenerator.php line 350 {"exception":"[object] (RuntimeException(code: 0): The file 'generated/pdf/Mon_Beau_Chateau_Roi_Des_Fôrets_Su-Per_04-2019_8ddb3a64c4.pdf' was not created (command: /var/www/html/gestImmo/bin/wkhtml2pdf --lowquality '/tmp/knp_snappy5ca4ac7a32b3d7.26041529.html' 'generated/pdf/Mon_Beau_Chateau_Roi_Des_Frets_Su-Per_04-2019_8ddb3a64c4.pdf'). at /var/www/html/gestImmo/vendor/knplabs/knp-snappy/src/Knp/Snappy/AbstractGenerator.php:350)"} []
这是控制器
/**
* @Route("/{id}/paid", name="rent_release_paid", methods={"GET"})
* @param RentRelease $rentRelease
* @param PdfGenerator $pdfGenerator
* @param MonthlyMailer $monthlyMailer
* @return Response
*/
public function rentIsPaid(
RentRelease $rentRelease,
PdfGenerator $pdfGenerator,
MonthlyMailer $monthlyMailer
): Response {
if (!$this->isGranted('EDIT_RENT_RELEASE', $rentRelease)) {
$this->addFlash('danger', 'Vous n\'etes pas autorisé à effectuer cette action.');
return $this->redirectToRoute('rent_release_index');
}
$rentRelease->setStatus('Payé');
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($rentRelease);
$entityManager->flush();
$pdfGenerator->generateRentReleasePdf($rentRelease); //I call the service here
$monthlyMailer->sendRentReleaseToLessees($rentRelease);
return $this->redirectToRoute(
'rent_release_pdf_delete',
['id' => $rentRelease->getId()]
);
}
这是我的服务:
/**
* @param RentRelease $rentRelease
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*/
public function generateRentReleasePdf(RentRelease $rentRelease)
{
$currentDate = new \DateTime();
$currentDate = $currentDate->format('m-Y');
if ($rentRelease->getStatus() === 'Payé') {
$propertyName = $rentRelease->getPropertyName();
$propertyName= str_replace(' ', '_', $propertyName);
$lesseeName = str_replace(' ', '-', $rentRelease->getLesseeName());
$fileName = $propertyName . '_' . $lesseeName . '_' . date("m-Y") . '_';
$fileName = $fileName . bin2hex(random_bytes(5)) . '.pdf';
$html = $this->twig->render('rent_release/pdf.html.twig', [
'rent_release' => $rentRelease,
'current_date' => $currentDate,
]);
$this->knpSnappyPdf->generateFromHtml("$html", "generated/pdf/$fileName"); // on the Stack Trace, the problem is here
$rentRelease->setPdf($fileName);
$this->manager->persist($rentRelease);
$this->manager->flush();
}
}
有人有想法吗?
答案 0 :(得分:0)
好的,问题是因为我选择的名称具有特殊字符
所以我在服务中添加了一个私有函数,我不知道哪种最干净的方法:
/**
* Created by PhpStorm.
* User: thocou
* Date: 12/03/19
* Time: 15:50
*/
namespace App\Service;
use App\Entity\RentRelease;
use DateTime;
use Doctrine\Common\Persistence\ObjectManager;
use Knp\Snappy\Pdf;
use Twig_Environment;
class PdfGenerator
{
/**
* @var Pdf
*/
private $knpSnappyPdf;
/**
* @var Twig_Environment
*/
private $twig;
/**
* @var ObjectManager
*/
private $manager;
/**
* PdfGenerator constructor.
* @param Pdf $knpSnappyPdf
* @param Twig_Environment $twig
* @param ObjectManager $manager
*/
public function __construct(Pdf $knpSnappyPdf, Twig_Environment $twig, ObjectManager $manager)
{
$this->knpSnappyPdf = $knpSnappyPdf;
$this->twig = $twig;
$this->manager = $manager;
}
/**
* Replacing accents in a string
* @param $string
* @return string
*/
private function removeAccents($string)
{
if (!preg_match('/[\x80-\xff]/', $string)) {
return $string;
}
$chars = array(
// Decompositions for Latin-1 Supplement
chr(195).chr(128) => 'A', chr(195).chr(129) => 'A',
chr(195).chr(130) => 'A', chr(195).chr(131) => 'A',
chr(195).chr(132) => 'A', chr(195).chr(133) => 'A',
chr(195).chr(135) => 'C', chr(195).chr(136) => 'E',
chr(195).chr(137) => 'E', chr(195).chr(138) => 'E',
chr(195).chr(139) => 'E', chr(195).chr(140) => 'I',
chr(195).chr(141) => 'I', chr(195).chr(142) => 'I',
chr(195).chr(143) => 'I', chr(195).chr(145) => 'N',
chr(195).chr(146) => 'O', chr(195).chr(147) => 'O',
chr(195).chr(148) => 'O', chr(195).chr(149) => 'O',
chr(195).chr(150) => 'O', chr(195).chr(153) => 'U',
chr(195).chr(154) => 'U', chr(195).chr(155) => 'U',
chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y',
chr(195).chr(159) => 's', chr(195).chr(160) => 'a',
chr(195).chr(161) => 'a', chr(195).chr(162) => 'a',
chr(195).chr(163) => 'a', chr(195).chr(164) => 'a',
chr(195).chr(165) => 'a', chr(195).chr(167) => 'c',
chr(195).chr(168) => 'e', chr(195).chr(169) => 'e',
chr(195).chr(170) => 'e', chr(195).chr(171) => 'e',
chr(195).chr(172) => 'i', chr(195).chr(173) => 'i',
chr(195).chr(174) => 'i', chr(195).chr(175) => 'i',
chr(195).chr(177) => 'n', chr(195).chr(178) => 'o',
chr(195).chr(179) => 'o', chr(195).chr(180) => 'o',
chr(195).chr(181) => 'o', chr(195).chr(182) => 'o',
chr(195).chr(182) => 'o', chr(195).chr(185) => 'u',
chr(195).chr(186) => 'u', chr(195).chr(187) => 'u',
chr(195).chr(188) => 'u', chr(195).chr(189) => 'y',
chr(195).chr(191) => 'y',
// Decompositions for Latin Extended-A
chr(196).chr(128) => 'A', chr(196).chr(129) => 'a',
chr(196).chr(130) => 'A', chr(196).chr(131) => 'a',
chr(196).chr(132) => 'A', chr(196).chr(133) => 'a',
chr(196).chr(134) => 'C', chr(196).chr(135) => 'c',
chr(196).chr(136) => 'C', chr(196).chr(137) => 'c',
chr(196).chr(138) => 'C', chr(196).chr(139) => 'c',
chr(196).chr(140) => 'C', chr(196).chr(141) => 'c',
chr(196).chr(142) => 'D', chr(196).chr(143) => 'd',
chr(196).chr(144) => 'D', chr(196).chr(145) => 'd',
chr(196).chr(146) => 'E', chr(196).chr(147) => 'e',
chr(196).chr(148) => 'E', chr(196).chr(149) => 'e',
chr(196).chr(150) => 'E', chr(196).chr(151) => 'e',
chr(196).chr(152) => 'E', chr(196).chr(153) => 'e',
chr(196).chr(154) => 'E', chr(196).chr(155) => 'e',
chr(196).chr(156) => 'G', chr(196).chr(157) => 'g',
chr(196).chr(158) => 'G', chr(196).chr(159) => 'g',
chr(196).chr(160) => 'G', chr(196).chr(161) => 'g',
chr(196).chr(162) => 'G', chr(196).chr(163) => 'g',
chr(196).chr(164) => 'H', chr(196).chr(165) => 'h',
chr(196).chr(166) => 'H', chr(196).chr(167) => 'h',
chr(196).chr(168) => 'I', chr(196).chr(169) => 'i',
chr(196).chr(170) => 'I', chr(196).chr(171) => 'i',
chr(196).chr(172) => 'I', chr(196).chr(173) => 'i',
chr(196).chr(174) => 'I', chr(196).chr(175) => 'i',
chr(196).chr(176) => 'I', chr(196).chr(177) => 'i',
chr(196).chr(178) => 'IJ',chr(196).chr(179) => 'ij',
chr(196).chr(180) => 'J', chr(196).chr(181) => 'j',
chr(196).chr(182) => 'K', chr(196).chr(183) => 'k',
chr(196).chr(184) => 'k', chr(196).chr(185) => 'L',
chr(196).chr(186) => 'l', chr(196).chr(187) => 'L',
chr(196).chr(188) => 'l', chr(196).chr(189) => 'L',
chr(196).chr(190) => 'l', chr(196).chr(191) => 'L',
chr(197).chr(128) => 'l', chr(197).chr(129) => 'L',
chr(197).chr(130) => 'l', chr(197).chr(131) => 'N',
chr(197).chr(132) => 'n', chr(197).chr(133) => 'N',
chr(197).chr(134) => 'n', chr(197).chr(135) => 'N',
chr(197).chr(136) => 'n', chr(197).chr(137) => 'N',
chr(197).chr(138) => 'n', chr(197).chr(139) => 'N',
chr(197).chr(140) => 'O', chr(197).chr(141) => 'o',
chr(197).chr(142) => 'O', chr(197).chr(143) => 'o',
chr(197).chr(144) => 'O', chr(197).chr(145) => 'o',
chr(197).chr(146) => 'OE',chr(197).chr(147) => 'oe',
chr(197).chr(148) => 'R',chr(197).chr(149) => 'r',
chr(197).chr(150) => 'R',chr(197).chr(151) => 'r',
chr(197).chr(152) => 'R',chr(197).chr(153) => 'r',
chr(197).chr(154) => 'S',chr(197).chr(155) => 's',
chr(197).chr(156) => 'S',chr(197).chr(157) => 's',
chr(197).chr(158) => 'S',chr(197).chr(159) => 's',
chr(197).chr(160) => 'S', chr(197).chr(161) => 's',
chr(197).chr(162) => 'T', chr(197).chr(163) => 't',
chr(197).chr(164) => 'T', chr(197).chr(165) => 't',
chr(197).chr(166) => 'T', chr(197).chr(167) => 't',
chr(197).chr(168) => 'U', chr(197).chr(169) => 'u',
chr(197).chr(170) => 'U', chr(197).chr(171) => 'u',
chr(197).chr(172) => 'U', chr(197).chr(173) => 'u',
chr(197).chr(174) => 'U', chr(197).chr(175) => 'u',
chr(197).chr(176) => 'U', chr(197).chr(177) => 'u',
chr(197).chr(178) => 'U', chr(197).chr(179) => 'u',
chr(197).chr(180) => 'W', chr(197).chr(181) => 'w',
chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y',
chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z',
chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z',
chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z',
chr(197).chr(190) => 'z', chr(197).chr(191) => 's'
);
$string = strtr($string, $chars);
return $string;
}
/**
* @param RentRelease $rentRelease
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
* @throws \Exception
*/
public function generateRentReleasePdf(RentRelease $rentRelease)
{
$currentDate = new DateTime();
$currentDate = $currentDate->format('m-Y');
if ($rentRelease->getStatus() === 'Payé') {
$propertyName = $rentRelease->getPropertyName();
$propertyName= str_replace(' ', '_', $propertyName);
$lesseeName = str_replace(' ', '-', $rentRelease->getLesseeName());
$fileName = $propertyName . '_' . $lesseeName . '_' . date("m-Y") . '_';
$fileName = $this->removeAccents($fileName);
$fileName = $fileName . bin2hex(random_bytes(5)) . '.pdf';
$html = $this->twig->render('rent_release/pdf.html.twig', [
'rent_release' => $rentRelease,
'current_date' => $currentDate,
]);
$this->knpSnappyPdf->generateFromHtml("$html", "generated/pdf/$fileName");
$rentRelease->setPdf($fileName);
$this->manager->persist($rentRelease);
$this->manager->flush();
}
}
}