【问题标题】:Generate a PDF and return a response生成 PDF 并返回响应
【发布时间】:2020-02-17 13:46:43
【问题描述】:

今天我遇到了在 symfony 上使用 KnpSnappyBundle 生成 PDF 的问题。

我正在使用 AJAX 运行路线,代码工作正常,但它不会生成 PDF,

我想在这里完成的是在新选项卡或窗口中生成 PDF 并向客户端返回成功消息。

这是我的代码:

 /**
 * @Route("/api/release_bills/{month}/{year}/{region}", name="api_print_bills", methods={"GET","POST"})
 * @param BillRepository $billRepository
 * @param ConsumptionRepository $consumptionRepository
 * @param Request $request
 * @param Snappy $snappy
 * @param $month
 * @param $year
 * @param $region
 * @return Response
 * @throws Exception
 */
public function releaseBills(BillRepository $billRepository,ConsumptionRepository $consumptionRepository, Request $request, Snappy $snappy,  $month,$year,$region ): Response
{
    $error = array();
    $success = array();
    if( $month>0 && $month<13 || preg_match("/^\d{4}$/",$year)||$region!=''){

        if($year>=2018 && $year <=2050){
            $entityManager = $this->getDoctrine()->getManager();

                $bills = $consumptionRepository->findAllWaterMetersForBilling($month,$year,$region);

                $isBillsExisted = $billRepository->findAllBillsByDate($month,$year,$region);

                if(empty($bills)){
                    array_push($error,['error'=>'there is not bills to be release for this criteria : [ city: '.$region.', year :'.$year.', and Month : '.$month.'!]']);
                    return new JsonResponse($error);
                }

                $arr = array();
                $newBills = array();
                $billsEnd=end($bills);

                foreach ($bills as $key=>$b){
                    $wmNumber =  $b->getWaterMeter()->getWmNumber();
                    $fullName = $b->getWaterMeter()->getClient()->getFullName();
                    $cin = $b->getWaterMeter()->getClient()->getCin();
                    $address= $b->getWaterMeter()->getAddress();
                    $wmAddress = $b->getWaterMeter()->getAddress()->getStreetAddress();
                    $city = $b->getWaterMeter()->getAddress()->getCity();
                    $zipCode = $b->getWaterMeter()->getAddress()->getZipCode();
                    $billCode = $b->getId();
                    $consumptionDate = $b->getDate();
                    $oldConsumption=$b->getPreviousRecord();
                    $newConsumption=$b->getCurrentRecord();
                    $printDate =new \DateTime('now');
                    $consumption=$b->getConsumption();
                    $cost = $b->getCost()+10;
                    $wmReferenceNumber = $b->getWaterMeter()->getWmReferenceNumber();
                    $client= $b->getWaterMeter()->getClient();
                    // tranche calculation
                    //==================================================
                    $tranche1 = $consumption >= 5 ? 5 : $consumption; //4
                    $tranche2 = $consumption - $tranche1 >= 5 ? 5: 0; //0
                    $tranche3 = $consumption - $tranche1 - $tranche2;
                    //==================================================
                    $bill = new Bill();
                    $bill->setCode($wmNumber);
                    $bill->setFullName($fullName);
                    $bill->setCin($cin);
                    $bill->setPrintDate($printDate);
                    $bill->setCost($cost);
                    $bill->setConsumption($consumption);
                    $bill->setConsumptionDate($consumptionDate);
                    $bill->setPreviousRecord($oldConsumption);
                    $bill->setNewRecord($newConsumption);
                    $bill->setWaterMeter($b->getWaterMeter());
                    $bill->setRegion($city);
                    $bill->setClient($client);
                    $entityManager->persist($bill);
                    array_push($arr,['wmAddress'=>$wmAddress,'city'=>$city,'zipCode'=>$zipCode,'tranche1'=>$tranche1,'wmNumber'=>$wmNumber,'fullName'=>$fullName,'cin'=>$cin,'address'=>strval($address),'billCode'=>$billCode,'consumptionDate'=>$consumptionDate,'oldConsumption'=>$oldConsumption,'newConsumption'=>$newConsumption,'printDate'=>$printDate,'consumption'=>$consumption,'cost'=>$cost,'wmReferenceNumber'=>$wmReferenceNumber]);

                    if(count($arr)==6||$billCode==$billsEnd->getId()){
                        array_push($newBills,$arr);
                        $arr = array();
                    }

                }

                $date = new \DateTime('now');
                $html= $this->renderView('bill/bill.html.twig', array(
                    'arrayBills'=>$newBills,
                ));


                if($isBillsExisted){
                    return new PdfResponse(
                        $snappy->getOutputFromHtml($html), "bill_".$date->format('Y-m-d').".pdf"
                    );
                }
                $entityManager->flush(); //Persist objects that did not make up an entire batch
                $entityManager->clear();

                return new PdfResponse(
                    $snappy->getOutputFromHtml($html), "bill_".$date->format('Y-m-d').".pdf"
                );

            }
        }
    array_push($success,['success'=>'bills were successfully released']);
    return new JsonResponse($success);
}

我的 AJAX 调用是:

 generatePDF = () =>{ 
        const {yearValue, monthValue, regionValue}= this.state;
        $.ajax({
            url: `http://symfony.localhost/bill/api/release_bills/${monthValue.value}/${yearValue.value}/${regionValue.value}`,
            success: function (data) {
                console.log('DATA',data)
            }.bind(this)
        });
    };

我相信我不能返回一个以上的响应,无论如何我已经对 ajax 调用的响应进行了控制台日志,显示了我想要从中生成 PDF 的页面的 HTML 内容,并且没有生成 PDF。

【问题讨论】:

    标签: javascript php symfony knp-snappy


    【解决方案1】:

    可能会更晚,但你可以这样尝试:

        $file = $folder . $fileName ;
    
        if (is_file($file)) {
            unlink($file);
        }
    

    然后您生成并保存具有相同名称及之后的文件。不要使用return new PdfResponse...,而是

    $pdf->generateFromHtml($html, $folder . $file);
    

    然后返回响应

        $response = new JsonResponse();
        $response->setStatusCode(Response::HTTP_NOT_FOUND); // 404
        if (is_file($file)) {
            $response->setStatusCode(Response::HTTP_OK); // 200
        }
    

    【讨论】:

      【解决方案2】:

      尝试像这样修改 Ajax:

      $.ajax({
        url: `http://symfony.localhost/bill/api/release_bills/${monthValue.value}/${yearValue.value}/${regionValue.value}`,
        success: function(data) {
          var blob=new Blob([data]);
          var link=document.createElement('a');
          link.href=window.URL.createObjectURL(blob);
          link.download="<CHOOSE_FILENAME_WITH_EXTENSION>";
          link.click();
        }
      });
      

      【讨论】:

      • 我按照你的建议试过了,但是好像没用,还是谢谢你
      【解决方案3】:

      在朋友的帮助下,我设法生成了 pdf,但我仍然不知道如何在生成 Pdf 时返回错误或成功消息。

      这就是我所做的:

      generatePDF = () =>{
          const {yearValue, monthValue, regionValue}= this.state;
      
          var strWindowFeatures = "location=yes,height=570,width=520,scrollbars=yes,status=yes";
          var URL = `http://symfony.localhost/bill/api/release_bills/${monthValue.value}/${yearValue.value}/${regionValue.value}`;
          window.open(URL, "_blank", strWindowFeatures);
      };
      

      函数 generatePDF 在 onClick 按钮上被调用

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-15
        • 2013-05-15
        • 2020-10-31
        • 2017-02-08
        相关资源
        最近更新 更多