javascript - KnpLabs/snappy bundle (wkhtmltopdf) 不呈现 Chart.js 图表

标签 javascript php symfony charts wkhtmltopdf

我尝试使用 Chart.js 库生成的图表生成 PDF 但 javascript 根本不呈现。

你看到我遗漏了什么吗?

   # config/packages/knp_snappy.yaml
    knp_snappy:
        pdf:
            enabled:    true
            binary:     '%env(WKHTMLTOPDF_PATH)%'
            options:
              debug-javascript: true
              enable-javascript: true
              javascript-delay: 200
              no-stop-slow-scripts: true

        image:
            enabled:    true
            binary:     '%env(WKHTMLTOIMAGE_PATH)%'
            options:    []

PHP Symfony 部分

    /**
     * Download pdf.
     *
     * @param string $slug
     * @param string $language
     *
     * @return Response
     *
     * @throws \Psr\Cache\CacheException
     * @throws \Psr\Cache\InvalidArgumentException
     */
    public function __invoke(string $slug, string $language): Response
    {
            $this->pdfFilesService->setPdfLanguage($language);
            $base64Images = $this->pdfFilesService->getBase64Images($slug);
            $profile      = $this->profileData->execute($slug, $language);
            $filename     = $profile['name'].'-report.pdf';
            $path         = $this->parameterBag->get('app.private_pdf_storage').'/'.$filename;

            $html = $this->templating->render('download_pdf.twig', \array_merge($base64Images, [
                'profile'     => $profile,
                'language'    => $language,
            ]));


            $this->pdf->generateFromHtml([$html], $path, [], true);

            return new Response(
                $path,
                200,
                [
                    'Content-Type'        => 'application/pdf',
                    'Content-Disposition' => 'inline; filename="'.$path.'"',
                ]
            );

    }

Twig

   <section>
       <div id="barMulti"></div>
   </section>
   <script type="text/javascript" src="{{ chartJs }}"></script>
   <script type="text/javascript">
      function getDataMulti(type) {
         return {
            // The type of chart we want to create
            type,

            // The data for our dataset
            data: {
               labels: [ ... ],
               datasets: [
                  {
                     backgroundColor: "#F4F7F9",
                     data: [3,7,4,5,5,2,6,8,9,7]
                  },
                  {
                     backgroundColor: "#66C4E0",
                     data: [3,7,4,5,5,2,6,8,9,7]
                  },
                  {
                     backgroundColor: "#009DCD",
                     data: [3,7,4,5,5,2,6,8,9,7]
                  },
               ]
            },

            // Configuration options go here
            options: {
               legend: {
                  display: false,
               },
               animation: {
                  duration: 0
               },
               scales: {
                  yAxes: [{
                     gridLines: {
                        color: "#454D57",
                     },
                     ticks: {
                        padding: 20,
                        fontStyle: 'bold',
                        fontColor: '#F4F7F9',
                        min: 0,
                        max: 100,
                     }
                  }],
                  xAxes: [
                     {
                        gridLines: {
                           color: "#454D57"
                        },
                        ticks: {
                           fontStyle: 'bold',
                           fontColor: '#F4F7F9',
                           padding: 20,
                           callback: function(label) {
                              if (/\s/.test(label)) {
                                 return label.split(" ");
                              }

                              return label;
                           }
                        }
                     }
                  ]
               }
            }
         }
      }

      // var barMulti = document.getElementById('barMulti');
      var barMulti = document.getElementById('barMulti');
      new Chart(barMulti, getDataMulti('bar'));
   </script>

最佳答案

wkhtmltopdf is not a perfect library but it is opensource and free to use, so we need to be grateful and try to help its usage or improve by contributing.

wkhtmltopdf GitHub Repo

作为第一步,您需要测试您的 HTML/TWIG 模板是否可以运行 Javascript。

<script>
  document.body.innerHTML = "Testing JavaScript PDF Rendering"
</script>

如果这不起作用,请检查您的 wkhtmltopdf 配置

  # config/packages/knp_snappy.yaml
    knp_snappy:
        pdf:
            enabled:    true
            binary:     '%env(WKHTMLTOPDF_PATH)%'
            options:
              debug-javascript: true
              enable-javascript: true
              javascript-delay: 1500
              no-stop-slow-scripts: true

在您确定 Javascript 在 wkhtmltopdf 中工作之后

最重要的事情。您需要用 styled div

包裹您的 canvas 元素
 <div class="reportGraph">
     <canvas id="barMulti"></canvas>
 </div>

并在 headcss 中放置样式类

   .reportGraph {
      width:850px
   }

或者通过内联 css 设计 Canvas 容器

然后在包含chart.js

之后添加这个脚本文件
<script>
  // wkhtmltopdf 0.12.5 crash fix.
  // https://github.com/wkhtmltopdf/wkhtmltopdf/issues/3242#issuecomment-518099192
  'use strict';
  (function(setLineDash) {
    CanvasRenderingContext2D.prototype.setLineDash = function() {
      if(!arguments[0].length){
        arguments[0] = [1,0];
      }
      // Now, call the original method
      return setLineDash.apply(this, arguments);
    };
  })(CanvasRenderingContext2D.prototype.setLineDash);
  Function.prototype.bind = Function.prototype.bind || function (thisp) {
    var fn = this;
    return function () {
      return fn.apply(thisp, arguments);
    };
  };
</script>

然后添加另一个 script 标记,您将在其中呈现图表。

<script>
function drawGraphs() {
    new Chart(
        document.getElementById("canvas"), {
            "responsive": false,
            "type":"line",
            "data":{"labels":["January","February","March","April","May","June","July"],"datasets":[{"label":"My First Dataset","data":[65,59,80,81,56,55,40],"fill":false,"borderColor":"rgb(75, 192, 192)","lineTension":0.1}]},
            "options":{}
        }
    );
}
window.onload = function() {
    drawGraphs();
};
</script>

关于javascript - KnpLabs/snappy bundle (wkhtmltopdf) 不呈现 Chart.js 图表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58917724/

相关文章:

javascript - ServiceWorker 中的 oninstall 与 onactivate 事件

javascript - ng-change 不适用于单选按钮

javascript - Canvas 图片麻烦

php - 检索多个YouTube用户的最新视频并按最新顺序排序

symfony2 从 onKernelRequest 抛出异常返回空白页

php - 使用 PHP 的 mysql_connect 功能的正确方法?

php - 使用 mysqli 插入数据

php - 带有 PHP 的 APNS 显示 SSL 损坏的管道错误

php - Symfony Ratchet WSS

jquery - 如何在不指定参数的情况下生成路线