8

我正在尝试使用 Google Charts 在 PDF 中生成多个图表。对于 PDF,我将 CakePDF 与 Wkhtmltopdf 引擎一起使用。不过,我似乎在将 Google Chart 代码实际加载到 PDF 中时遇到了问题。这是我当前的 Javascript 代码。

<script type="text/javascript" src="https://www.google.com/jsapi">
</script>
<script type="text/javascript">
google.load('visualization', '1.0', {'packages':['corechart']});
//setTimeout(function() {google.load('visualization', '1.0', {'packages':['corechart']});}, 100);
google.setOnLoadCallback(drawChart);
function drawChart(doIt,taken, total, element) 
{
    if (typeof doIt === 'boolean')
    {
        var data = new google.visualization.DataTable();
        data.addColumn('string', 'Type');
        data.addColumn('number', 'Courses');
        data.addRows([
          ['Taken', taken],
          ['Remaining', total - taken]
        ]);
        var options = {
                       'width':40,
                       'height':40};
        var chart = new google.visualization.PieChart(document.getElementById(element));
        chart.draw(data, options);
    }
 }
</script>

问题是,当我为可视化包执行 google.load 时,它会导致 Wkhtmltopdf 返回错误,指出引擎未返回任何数据。我发现了一个我认为类似的问题,为什么 google.load 会导致我的页面变为空白?所以我试着做 setTimeout(function() {google.load('visualization', '1.0', {'packages':['corechart']});}, 100); 这个解决方案的问题是,如果延迟太低,页面将返回没有错误,但它会完全空白;但是,如果我将延迟设置得太高,页面将不会加载包并且 Javascript 将中断

var data = new google.visualization.DataTable();

当我调用该函数时。此外,该海报说明了 document.write() 的问题,但如果我在将内容添加到页面之前或之后添加 document.write() 行,我没有问题。如果有人知道如何让 Google Charts 与 Wkhtmltopdf 一起工作并且可以帮助我,我将不胜感激。


好的,为了给 API 更多的加载时间,我将调用函数的位置移到了 PHP 的末尾。现在,它只设置一个需要在其中绘制图形的元素数组和适当的值,然后使用数组中的值调用函数。我不确定现在是什么问题,因为它正在中断chart.draw(data, options);。它似乎正在获取正确的值和传递给它的元素。

这看起来真的很迂回,因为它是。无论出于何种原因,Wkhtmltopdf 都无法读取我放入 javascript 标签中的任何内容。我已经尽我所能让它阅读它,但它就是不会哈哈。CakePDF 插件可以读取 Javascript,所以我的 JS 代码是默认的 PDF 布局。然后在 WkhtmltoPdf 呈现的实际视图中,我创建了一个元素和值的数组。然后我这样做(在许多不同的可能解决方案之后,这是我能够调用 JS 函数的唯一方法)

for ($i = 0; $i < sizeof($grade_array); $i++)
{
    $element = $grade_array[$i][2];
    echo '<script type="text/javascript">drawChart(true, '.$this->Js->value($grade_array[$i][0]).', '.$this->Js->value($grade_array[$i][1]).','.json_encode($element).');</script>';
}

它似乎传递了所有正确的数据。调用该函数后,我有打印参数的调试行,并且所有参数都正确打印。我还注意到,如果我在与 chart.draw() 相同的位置执行 document.write('test'),它将写入 'test' 而不会出现任何错误。出于某种原因,如果我执行 chart.draw(),它只是说 Wkhtmltopdf 没有返回任何数据。

4

8 回答 8

8

问题: 当使用 wkhtmltopdf / wkhtmltoimage html 页面上的 pdf / 图像(使用 Google 图表)时,它不包含 Google 图表。输出(pdf / png)在谷歌图表应该显示的位置只是空白。当然,原始的 html 页面还可以。

解决方案: 我通过替换解决了这个问题(Google Charts + wkhtmltopdf):

<script src="http://www.gstatic.com/charts/loader.js"></script>

经过

<script src="http://www.google.com/jsapi"></script>

不知何故,wkhtmltopdf 库无法处理包含第一个 javascript 包含的 Google Chart html 页面。

于 2016-03-18T08:10:21.013 回答
3

我今天自己解决了这个问题,所以这对我来说是有效的。如需更详细的演练,欢迎您阅读我关于该主题的博客文章。

我只需要进行两个简单的更改即可使其正常工作:

  1. 提供javascript-delay论据,例如javascript-delay 1000。这会将 JavaScript 代码的执行延迟 1000 毫秒
  2. 加载 Google Visualization API 时添加回调

function init() {
  google.load("visualization", "1.1", {
    packages: ["corechart"],
    callback: 'drawCharts'
  });
}

然后,您可以简单地实现drawCharts可以像往常一样绘制图表的功能。

确保您的标记包括以下内容:

<body onload="init()">
    <div id="my-chart"></div>
</body>

只需将您的图表绘制到具有上述 ID 的 div 上,您就可以开始了。

注意:我使用的是最新的可用二进制文件(截至目前为 0.12.0)。在 64 位 Ubuntu 安装上测试。

于 2014-03-17T21:11:21.030 回答
2

最近遇到了这个问题。我已经尝试了所有解决方法来解决加载问题 - 延迟、setInterval、setTimeout。还尝试升级 wkhtml 版本。

对我有用的是明确定义要使用的 Google Charts 版本号。在我的情况下,版本 44。

<script>google.load("visualization", "44", {packages:["corechart"]});</script>

注意:现在使用版本“1”意味着您正在使用当前版本。根据 Google 文档 - “所有 'jsapi' 请求现在都被重定向到新的加载程序。如果您正在加载版本 '1' 或 '1.0',您现在将加载 'current'。”

于 2020-07-28T10:43:26.360 回答
2

而不是使用该javascript-delay选项,您实际上应该等待使用window-status. window-status使 wkhtmltopdf 等到窗口状态具有所需的值。

向图表添加事件侦听器

google.visualization.events.addListener(tableChart, 'ready', myReadyHandler);
function myReadyHandler(){
  window.status = "ready";
}

使用运行 wkhtmltopdf--window-status ready

于 2016-02-24T10:56:21.130 回答
1

我也有使用问题

window.onload = function () {
   google.charts.load("current", {packages:["corechart", "timeline", "bar"]});
   google.charts.setOnLoadCallback(drawCharts);
};

QT 引擎从不启动 drawCharts,因此不会在 PDF 中呈现图表(也使用 QTWeb 浏览器验证)。

我终于用一种不太优雅的方式解决了

window.onload = function () {
   google.charts.load("current", {packages:["corechart", "timeline", "bar"]});
   setTimeout(function(){drawCharts();}, 500);
};
于 2018-07-05T09:06:38.743 回答
1

谷歌图表一点都不好。我对谷歌图表有很多问题。我正在使用 D3 库https://d3js.org v5.9.2。

一切都好。

您可以找到如何执行此操作的示例。我用了那个例子https://wizardace.com/d3-piechart/

于 2019-06-24T15:07:37.430 回答
0

它正在使用以下代码。

<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>

并添加超时/等待直到加载。

 google.charts.load('current', {packages: ['corechart']});
    var interval = setInterval(function() {
      if (
        google.visualization !== undefined
        && google.visualization.DataTable !== undefined
        && google.visualization.PieChart !== undefined
      ){
        clearInterval(interval);
        window.status = 'ready';
        drawCharts();
      }
    }, 100);
于 2020-03-31T09:19:48.723 回答
0

如果您在 2020 年 7 月 ~ 5 月之后遇到此问题并且您的脚本正在运行,但现在没有更多,您必须知道为什么 Google 已弃用http://www.google.com/jsapi中的脚本版本现在他们正在重定向与 wkhtmltopdf 不兼容的http://www.gstatic.com/charts/loader.js的请求。

因此,要回到旧版本,您必须像这样改进您的代码:

<script type="text/javascript" src="http://www.google.com/jsapi"></script>
        
<script type="text/javascript">
function init() {
    //the latest version who worked for me was the 44. 45 and above not worked anymore.
    google.load("visualization", "44", {packages:["corechart"]});
    var interval = setInterval(function() {
        if ( google.visualization !== undefined && google.visualization.DataTable !== undefined && google.visualization.PieChart !== undefined ){ clearInterval(interval);
        window.status = 'ready';
        drawCharts(); //call here your callback who will render the chart
        }
    }, 100);
}
</script>

并使用此选项告诉 wkhtmltopdf 在 window.status 准备好时开始渲染 pdf:

--window-status ready

于 2020-10-21T19:09:23.147 回答