问题
I am using yii framework 1.14 with php on centos 5. I have designed a view that contains 4 graphs created using highcharts. i want to export this page to pdf from my controller/action method. The following is what I have so far. the html gets produced fine but when i try to export to pdf i only get the headers in the view and no graphs.
controller/action
if(isset($_GET['report'])){
$graphs = 4;
$arr = array();
$where = array(
array("PROJCODE"=>array("Woking","Cairo"),"MC"=>array("MC")),
array("PROJCODE"=>array("Houston","Cairo"),"MC"=>array("MC")),
array("PROJCODE"=>array("Jakarta"),"MC"=>array("MC")),
array("MC"=>array("P")),
);
$title = array(
array("Woking & Cairo"),
array("Houston & Cairo"),
array("Jakarta"),
array(""),
);
for ($i = 0; $i < $graphs; $i++) {
$model=new ViewWebprojectreport('weeklystatus');
$model->unsetAttributes();
$dataProvider = $model->weeklystatus($where[$i] );
$dataProvider->pagination->pageSize = $model->count();
//print_r($dataProvider);
$blank = array();
foreach ($dataProvider->getData() as $data) {
$blank[] = $data;
}
$count = 0;
$command = array();
foreach ($dataProvider->getData() as $data) {
$count++;
$command[$count]["PROJECT"] = $data->PROJECT;
$command[$count]["StartDATE"] = $data-> StartDATE;
$command[$count]["ProjectEndDate"] = $data-> ProjectEndDate;
$command[$count]["PERCENT"] = $data-> PERCENT;
$command[$count]["MC"] = $data-> MC;
$command[$count]["MC"] = $data->ActualEndDate;
$count++;
}
$totalprojects = $count;
$cat = array();
$totalLength = array();
$schedule = array();
$complete = array();
$planned = array();
$totalprojects = count($command);
$scrollcount = 0;
if(count($command)>20)
$scrollcount = count($command) - 10; // set scrollbar depending on records returned
foreach ($command as $key => $value) {
$cat[] = $value['PROJECT'];
$date_from = (strtotime($value['StartDATE']) )*1000;
$date_to = (strtotime($value['ProjectEndDate']) + 1*86400)*1000;
if($value['MC'] == -1)
$totalLength[] = array("low"=>$date_from,"high"=>$date_to, "color"=>"#2f7ed8");
elseif($value['MC'] == 0)
$totalLength[] = array("low"=>$date_from,"high"=>$date_to, "color"=>"#0d233a");
else
$totalLength[] = array($date_from,$date_to);
$today = time();
$startdate = strtotime($value['StartDATE']);
$enddate = strtotime($value['ProjectEndDate']);
if( $value['ProjectEndDate'] == ""){
$enddate = $startdate;
}
$diff_total = $enddate - $startdate;
$diff_today = $today - $startdate;
$schedule[] = array( $date_from, $today*1000 );
// work out number of days completed by percent complete of project
$percentage_to_get = round((float)$value['PERCENT'],2);
$percentage_of_days = ((int)$value['PERCENT'] == 0)? 0 : floor($diff_total/100*$percentage_to_get);
$percentComplete = (($startdate + $percentage_of_days)+ 1*86400)*1000;
$complete[] = (float) $value['PERCENT'];
$planned[]=($diff_today != 0 && $diff_total != 0) ? ( ((($today - $startdate) / ($enddate - $startdate))*100) > 100 ) ? 100 : (($today - $startdate) / ($enddate - $startdate))*100 : 0;
}
$arr[] = array('cat'=>$cat,
//"data"=>$totalLength,
"complete"=>$complete,
"planned"=>$planned,
"totalprojects"=>$count,
"title"=>$title[$i],
"key"=>$i);
//echo $i;
//print_r($arr);
//echo "<br><br>";
}
$this->layout = 'weekly_status_graph';
$html = $this->renderPartial('weekly_status_graph',array("arr"=>$arr),true);
/*
# mPDF
$mPDF1 = Yii::app()->ePdf->mpdf();
# You can easily override default constructor's params
$mPDF1 = Yii::app()->ePdf->mpdf('', 'A4');
# render (full page)
$mPDF1->WriteHTML($html);
# Load a stylesheet
//$stylesheet = file_get_contents(Yii::getPathOfAlias('webroot.css') . '/main.css');
//$mPDF1->WriteHTML($stylesheet, 1);
# renderPartial (only 'view' of current controller)
//$mPDF1->WriteHTML($this->renderPartial('index', array(), true));
# Renders image
//$mPDF1->WriteHTML(CHtml::image(Yii::getPathOfAlias('webroot.css') . '/bg.gif' ));
# Outputs ready PDF
$mPDF1->Output();
*/
$pdf = $this->createPdf();
$pdf->setOptions(array('orientation'=>'Landscape',
'margin-top' => 0,
'margin-right' => 10,
'margin-bottom' => 0,
'margin-left' => 10,
)
);
//$this->layout = 'pdf';
$pdf->renderPage('weekly_status_graph',array("arr"=>$arr));
$this->render('weekly_status_graph',array("arr"=>$arr));
$pdf->send('w'.date('M-Y').'.pdf');
view
<head>
<script src="<?php echo Yii::app()->request->baseUrl; ?>/js/jquery-2.1.0.js"></script>
<script
type="text/javascript"
src="<?php echo Yii::app()->request->baseUrl; ?>/js/highcharts/highstock.js"></script>
<script
type="text/javascript"
src="<?php echo Yii::app()->request->baseUrl; ?>/js/highcharts/highcharts-more.js"></script>
<script
type="text/javascript"
src="<?php echo Yii::app()->request->baseUrl; ?>/js/highcharts/modules/exporting.js"></script>
<script>
function redyellowgreen(x){
//console.log($(x).parent());
$(x).attr('fill','url(#MyGradient)');
}
function createGradient(svg,id,stops){
var svgNS = svg.namespaceURI;
var grad = document.createElementNS(svgNS,'linearGradient');
grad.setAttribute('id',id);
for (var i=0;i<stops.length;i++){
var attrs = stops[i];
var stop = document.createElementNS(svgNS,'stop');
for (var attr in attrs){
if (attrs.hasOwnProperty(attr)) stop.setAttribute(attr,attrs[attr]);
}
grad.appendChild(stop);
}
var defs = svg.querySelector('defs') || svg.insertBefore( document.createElementNS(svgNS,'defs'), svg.firstChild );
return defs.appendChild(grad);
}
</script>
</head>
<body>
<h1>Multiclient Projects</h1>
<?php foreach ($arr as $key=>$value){?>
<?php if($key==3)
echo "<h1>Propiertary Projects</h1>";
?>
<div id="weekly_status_graph<?=$key?>" style="height:600px;width: 900px;">
<?php $this->renderPartial('weekly_status_graph_template',$value);?>
</div>
<?php }?>
</body>
view2
<script>
$(document).ready(function(){
//function buildColumnGraph(data){
var projects_title = <? echo json_encode($title);?>;
$('#weekly_status_graph<?=$key?>').highcharts({
//var chart = new Highcharts.Chart({
chart:{
type:'column',
//inverted:true,
//renderTo: 'container'
},
title:{
text:projects_title
},
xAxis:{
categories:<? echo json_encode($cat); ?>,
//min: data.scroll,
labels: {
rotation: -45,
align: 'right',
style: {
fontSize: '13px',
fontFamily: 'Verdana, sans-serif'
}
}
},
yAxis:{
min:0,
max:100,
title: {
text: '% COMPLETE'
},
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0
}
},
tooltip:{
formatter: function(){
if(this.series.name == "Actual"){
return "Actual POC " + this.y + "%";
}else if(this.series.name == "Planned"){
return "Planned POC " + this.y + "%";
}
}
},
legend:{
enabled:true,
verticalAlign:'top',
align:'right',
floating: true,
},
credits: {
enabled: false
},
exporting: {
enabled: false,
},
series:[
{
'name':'Planned',
'data':<? echo json_encode($planned); ?>,
'color': "rgb(91,155,213)"
},
{
name:'Actual',
data:<? echo json_encode($complete); ?>,
color: 'rgb(237,125,49)'
}
]
}); // end of columngraph
// create linear gradient for legend in 2 graph
createGradient($('svg')[0],'MyGradient',[
{offset:'3%', 'stop-color':'red'},
{offset:'95%','stop-color':'#10f200'}
]);
//}
});
</script>
If i put on the view and use my pdf printer to create pdf. it creates the x and y axis of the graphs but no columns.
UPDATE
I am trying to do the following which shoudl create the image and place in temp dir. I have set up highcharts to use local exporting server.
var data = "filename="+<?=$key?> + "&type=image/png&width=900px&scale=2&svg="+$("#weekly_status_graph<?=$key?>").children("div").contents("svg");
$.ajax({
type: "POST",
url: '<?php echo Yii::app()->request->baseUrl;?>/protected/extensions/highcharts/exporting-server/php/php-batik/index.php',
data:data,
success : function(data) {
}
});
The jquery result i get is
<pre>About to transcode 1 SVG file(s)
Converting 5ea8ca9b4530955b6076e033627b1f49.svg to temp/5ea8ca9b4530955b6076e033627b1f49.png ... ... error (SVGConverter.error.while.rasterizing.file)
</pre>Error while converting SVG.
<h4>Debug steps</h4>
<ol>
<li>Copy the SVG:<br/><textarea rows=5>[object Object]</textarea></li>
<li>Go to <a href='http://validator.w3.org/#validate_by_input' target='_blank'>validator.w3.org/#validate_by_input</a></li>
<li>Paste the SVG</li>
<li>Click More Options and select SVG 1.1 for Use Doctype</li>
<li>Click the Check button</li>
</ol>
This passes an SVG object to batik. what do i need to correct?
回答1:
I have installed phantomjs
in my controller, created an array and encoded it with json with output to file. Then used phantomjs
to convert it to image. See the code below.
I am using Yii
and have highcharts
located in the extensions folder which contains everything I need. I had to download and place batik
in that directory.
$json = json_encode(array(
"chart"=>array(
"type"=>'column',
"width"=>1000,
"height"=>350
),
"title"=>array(
"text"=>$title[$i]
),
"xAxis"=>array(
"categories"=>$cat,
"labels"=>array(
"rotation"=>$rotation,
"align"=>'left',
"style"=>array(
"fontSize"=>'8px',
"fontFamily"=>'Verdana, sans-serif',
"width"=>"75px"
)
)
),
"yAxis"=>array(
"min"=>0,
"max"=>100,
"title"=>array(
"text"=>'% COMPLETE'
),
"tickInterval"=>10
),
"plotOptions"=>array(
"column"=>array(
"pointPadding"=> 0.2,
"borderWidth"=> 0
)
),
"legend"=>array(
"enabled"=>true,
"verticalAlign"=>'middle',
"align"=>'right',
//"floating"=> true
),
"credits"=>array(
"enabled"=> false
),
"series"=>array(
array(
'name'=>'Planned',
'data'=>$planned,
'color'=> "rgb(91,155,213)"
),
array(
"name"=>'Actual',
"data"=>$complete,
"color"=>'rgb(237,125,49)'
)
)
));
$file = "protected/extensions/highcharts/exporting-server/php/php-batik/temp/$i.json";
// Write the contents back to the file
file_put_contents($file, $json);
// generates images to use for weekly status report
shell_exec("/usr/local/bin/phantomjs protected/extensions/highcharts/exporting-server/phantomjs/highcharts-convert.js -infile protected/extensions/highcharts/exporting-server/php/php-batik/temp/${i}.json -outfile images/$i.png -constr Chart");
来源:https://stackoverflow.com/questions/21907904/how-to-auto-create-pdf-using-highchart-graphs