mikehaertl/phpwkhtmltopdf wrapper - Works when running PHP file from command line - php

I have made the following file:
test.php
<?php
require 'vendor/autoload.php';
use mikehaertl\wkhtmlto\Pdf;
$htmlString = <<<EOT
<!DOCTYPE html>
test
</html>
EOT;
$pdf = new Pdf($htmlString);
$pdf->setOptions(array(
'orientation' => 'landscape'
));
$pdf->saveAs('new.pdf');
?>
When I run from the command line (Ubuntu 12.x):
sudo php test.php
I get a file that shows up in my directory and works as intended. However now take the following file where I am trying to apply the above to a real world scenario - note: when I echo $htmlString I get a valid and expected string.
testPDF.php
<?php
// Start session and check if user is logged in
session_start();
if(!isset($_SESSION['permission']))
{
die('Please login.');
}
// Dependencies
require 'vendor/autoload.php';
use mikehaertl\wkhtmlto\Pdf;
require 'database.php';
// Initialize
$client = $db->real_escape_string($_GET['client']);
$start_date = $db->real_escape_string($_GET['start_date']);
$end_date = $db->real_escape_string($_GET['end_date']);
$jobs = array();
$htmlString = '';
// Get list of jobs from DB & save to array
$query = "SELECT somecolumns FROM mydatabase WHERE start_date > '{$start_date}' AND end_date < '{$end_date}' AND client = '{$client}'";
if(!$result = $db->query($query))
{
die('There was an error running the query [' . $db->error . ']');
}
while($r = mysqli_fetch_assoc($result))
{
$jobs[] = $r;
}
// Loop through jobs array and formulate HTML string
foreach($jobs as $value)
{
$id = $value['id'];
$name = $value['name'];
$tech = $value['tech'];
$time_closed = $value['time_closed'];
$time_total = $value['time_total'];
$time_charged = $value['time_charged'];
$description = $value['description'];
$htmlString = $htmlString . <<<EOT
<h4 style="text-align: center;">{$id} - {$name}</h5>
<table id="simple-table" class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th style="width: 180px;">Date</th>
<th>Description</th>
<th style="width: 50px;">Duration</th>
<th style="width: 150px;">Time Charged</th>
<th style="width: 150px;">Technician</th>
</tr>
</thead>
<tbody id="jobs_start">
<tr>
<td>{$time_closed}</td>
<td>{$description}</td>
<td>{$time_total}</td>
<td>{$time_charged}</td>
<td>{$tech}</td>
</tr>
</tbody>
</table>
EOT;
}
$pdf = new Pdf($htmlString);
$pdf->setOptions(array(
'orientation' => 'landscape'
));
$pdf->saveAs('new.pdf');
?>
When I try to run the above by browsing to testPDF.php as a logged in user, I get nothing. No file is generated and no error/warning in the error logs. I've tried using $pdf->send() as well but no success.
My initial thought that this is a permissions issue, however I've tried setting testPDF.php to owner root and permission 755 but it still does not resolve the issue.

The issue is that when sending a HTML string to the pdf object, it looks for the tag to determine if it's html.
The first example has a HTML tag, while the 2nd file does not have any html tag thus is fails, silently.
https://github.com/mikehaertl/phpwkhtmltopdf/blob/master/src/Pdf.php

Related

Mpdf\MpdfException: Word is too long to fit in table

When I try to parse my html data which contain tables, it gives me error.
Fatal error: Uncaught Mpdf\MpdfException: Word is too long to fit in
table - in
/home/users/rajat.agarwal/www/html/mve_493_sp3/app/addons/wk_invoice/lib/vendor/mpdf/mpdf/src/Mpdf.php
on line 19056
$mpdf = new \Mpdf\Mpdf();
$mpdf->use_kwt = true;
// $mpdf->showImageErrors = true;
$html = '
<table>
<tr>
<td>Your table data</td>
</tr>
</table>
<div style="page-break-after: always;"> </div>
';
$mpdf->curlAllowUnsafeSslRequests = true;
$mpdf->table_error_report = true;
// $mpdf->shrink_tables_to_fit=0;
$mpdf->WriteHTML(
$html
);
$mpdf->Output();exit;
I have already tried many solution like autosize="1" or $mpdf->shrink_tables_to_fit=0; but not one works for me.
Composer.json
{
"require": {
"mpdf/mpdf": "^8.0"
}}

generate an Excel file using PHP

I'm new with PHP, I'm developping a WEB application that display a table with informations from an SQL server DATA BASE, the problem that I want to add a button to generate an EXCEL file that contains the table displayed? Is that possible??
#Ranjit this is the PHP code that displays the table and generate the excel file
edit 1
<?php
$ch="";
if(isset($_POST['historique']))
{
if ((!empty($_POST['Date_de_debut']))&& (!empty($_POST['Date_de_fin']))&&(!empty($_POST['Heure_de_debut']))&&(!empty($_POST['Heure_de_fin'])))
{
$ch= "(CONVERT(Datetime, '".$_POST['Date_de_debut']." ".$_POST['Heure_de_debut'].".000',120)) and (CONVERT(Datetime, '".$_POST['Date_de_fin']." ".$_POST['Heure_de_fin'].".000',120))";
?>
<table id="tab" border="1">
<tr>
<th><font color="red">Date</font></th>
<th><font color="red">Agent</font></th>
<th><font color="red">numéro</font></th>
</tr>
<?php
$search = " // my query
where operationDate between" .$ch;
$stmt = mssql_query($search);
while ($data = mssql_fetch_assoc($stmt))
{
?>
<tr>
<td><?php echo utf8_encode ($data['operationDate']);?></td>
<td><?php echo utf8_encode ($data['fullName']);?></td>
<td><?php echo utf8_encode ($data['number']);?></td>
</tr>
<?php
} }
?>
</table>
<?php
}
$output ='';
if(isset($_POST['excel']))
{
if ((!empty($_POST['Date_de_debut']))&& (!empty($_POST['Date_de_fin']))&&(!empty($_POST['Heure_de_debut']))&&(!empty($_POST['Heure_de_fin'])))
{
$rq = "// my query
where operationDate between" ."(CONVERT(Datetime, '".$_POST['Date_de_debut']." ".$_POST['Heure_de_debut'].".000',120)) and (CONVERT(Datetime, '".$_POST['Date_de_fin']." ".$_POST['Heure_de_fin'].".000',120))";
$res = mssql_query($rq);
if(mssql_num_rows($res)>0)
{
$output.='<table border=1>
<tr>
<th>Date</th>
<th>Depanneur</th>
<th>numéro</th>
</tr>
';
while ($row=mssql_fetch_array($res))
{
$output .='
<tr>
<td>'.$row["operationDate"].'</td>
<td>'.$row["fullName"].'</td>
<td>'.$row["number"].'</td>
</tr>';
}
$output .='</table>';
header("Content-Type: application/xls;charset=UTF-8");
header("Content-Disposition: attachement; filename=file.xls");
echo $output;
//mssql_close($conn);
}}}
?>
You'll have to select the data manually then insert them into the excel sheet, there's php library called PHPEXCEL you can use it.
See this
http://www.c-sharpcorner.com/article/export-to-excel-in-php-with-my-sql/
There are some nice packages out there to generate excel files such as
Box Spout and PHP Spreadsheet.
The documentation of both packages is very clear any you will be generating excel files within minutes of browsing through documentation.
Yes,
It is possible. You can follow this
1) Connect to database:
2) Define a filename of excel
//define separator (defines columns in excel & tabs in word)
$sep = "\t"; //tabbed character
$fp = fopen('database.xls', "w");
$schema_insert = "";
$schema_insert_rows = "";
//start of printing column names as names of MySQL fields
Sources - http://www.anillabs.com/2010/03/how-to-create-excel-file-with-mysql-data-using-php-code/

How to retrieve info from MySQL using JSON?

I'm practicing using JSON but seems it's not retrieving the info intended.
The page shows the user details from database using JSON directly on the HTML output.
getjson
</p>
<?php
$mysql_db_hostname = "host";
$mysql_db_user = "user";
$mysql_db_password = "pass";
$mysql_db_database = "db";
$con = #mysqli_connect($mysql_db_hostname, $mysql_db_user, $mysql_db_password,
$mysql_db_database);
if (!$con) {
trigger_error('Could not connect to MySQL: ' . mysqli_connect_error());
}
$var = array();
$sql = "SELECT * FROM users";
$result = mysqli_query($con, $sql);
while($obj = mysqli_fetch_object($result)) {
$var[] = $obj;
}
echo '{"users":'.json_encode($var).'}';
?>
<p style="text-align: justify;">
and in showjson
</p>
<table class="mGrid" id="jsondata">
<thead>
<th>Id</th>
<th>Name</th>
<th>Age</th>
<th>Gender</th>
<th>Location</th>
</thead>
<tbody></tbody>
</table>
</div>
<script type="text/javascript">
$(document).ready(function(){
var url="getjson.php";
$("#jsondata tbody").html("");
$.getJSON(url,function(data){
$.each(data.users, function(i,user){
var newRow =
"<tr>"
+"<td>"+user.id+"</td>"
+"<td>"+user.name+"</td>"
+"<td>"+user.age+"</td>"
+"<td>"+user.gender+"</td>"
+"<td>"+user.location+"</td>"
+"</tr>" ;
$(newRow).appendTo("#jsondata tbody");
});
});
});
</script>
<p style="text-align: justify;">
database users with id,name,gender,location
You have a trailing <p style="text-align: justify;"> on your JSON which renders it invalid so it will not parse.
Remove it.
You should have examined the data you got back from the PHP (either by accessing it though your browser's developer tools Net tab or accessing the URL directly). You could have then tested the JSON with a tool like JSON Lint.
PHP will, by default, claim that anything it outputs is HTML. While your use of getJSON will tell jQuery to ignore that and parse it as JSON anyway, best practise would be to include header("Content-Type: application/json");.
Best practise would also be to generate all your JSON using json_encode instead of wrapping {"users": and } around it with string concatenation.

PHP Simple HTML DOM Parser works on localhost but not live WordPress website

I am working with a WordPress plugin that outputs a table of data on the plugin's admin page. I have modified the plugin to add a button on the page that exports the table of data into a CSV file. Everything works perfectly on my localhost, but after transferring to the live server, it no longer works - the CSV file that is exported is blank. I am using PHP Simple HTML DOM Parser to parse the HTML table and convert it to CSV, and this seems to be where the roadblock is happening.
I have added the export button with this code (parts of the URL hidden for privacy):
<form action="**website-url**/wp-content/plugins/**plugin**/includes/votes-logs-export.php" method="POST">
<input type="submit" value="<?php _e('Export Table as CSV','**plugin**'); ?>" class="button" id="export" name="export" />
</form>
My file votes-logs-export.php has this code:
require_once('../../../../wp-load.php');
include 'simple_html_dom.php';
$file_name = "contest_votes_".date('d-m-Y-H-i-s').'.csv';
header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=".$file_name);
global $wpdb;
$export_sql = "SELECT log.*,pst.post_title FROM ".$wpdb->prefix."votes_tbl as log LEFT JOIN ".$wpdb->prefix."posts as pst on log.post_id=pst.ID ORDER BY pst.post_title DESC";
$export_logs = $wpdb->get_results($export_sql, OBJECT);
if (!empty($export_logs)) {
$fp = fopen("php://output", "w");
if ($wpdb->num_rows > 0) {
$output = '';
foreach ($export_logs as $logs) {
$vote_id = $logs->post_id;
$postdata = get_posts($vote_id);
$vote_author_id = $postdata[0]->post_author;
$vote_author = get_the_author_meta( 'display_name', $vote_author_id );
$voter_name = $logs->ip;
if(filter_var($voter_name, FILTER_VALIDATE_IP) !== false)
$voter_name = $logs->ip;
else
$voter_name = get_the_author_meta( 'display_name', $voter_name );
$voted_date = $logs->date;
$output .= '
<tr>
<td>'.$logs->post_title.'</td>
<td class="author column-author">'.$vote_author.'</td>
<td class="author column-author">'.$voter_name.'</td>
<td class="author column-author">'.$voted_date.'</td>
</tr>';
}
}
$table = '
<table>
<tr>
<th>Title</th>
<th>Author</th>
<th>Voter</th>
<th>Vote Date</th>
</tr>' . $output . '</table>';
$html = str_get_html($table);
foreach($html->find('tr') as $element){
$td = array();
foreach( $element->find('th') as $row){
$td [] = $row->plaintext;
}
// prevent blank rows being inserted into CSV file
if (!empty($td)) {
fputcsv($fp, $td);
}
$td = array();
foreach( $element->find('td') as $row){
$td [] = $row->plaintext;
}
// prevent blank rows being inserted into CSV file
if (!empty($td)) {
fputcsv($fp, $td);
}
}
fclose($fp);
}
I'm able to view the PHP page in order to debug by commenting out the header redirects. On my localhost, the PHP page outputs the table data in CSV format, but on the live server, it's a blank page. (No errors on the page or in error_log.) I have debugged this code and found that $table and all of the code above it seems to be running perfectly - if I print the contents of $table I get a formatted HTML table of my data:
<table>
<tbody>
<tr>
<th>Title</th>
<th>Author</th>
<th>Voter</th>
<th>Vote Date</th>
</tr>
<tr>
<td>Writing-on-Stone Park</td>
<td class="author column-author">admin</td>
<td class="author column-author">email#email.com</td>
<td class="author column-author">2014-07-04 16:42:57</td>
</tr>
<tr>
<td>White Tailed Ptarmigan</td>
<td class="author column-author">admin</td>
<td class="author column-author">email#email.com</td>
<td class="author column-author">2014-07-04 06:07:51</td>
</tr>
<tr>
<td>Rockbound Lake</td>
<td class="author column-author">admin</td>
<td class="author column-author">email#email.com</td>
<td class="author column-author">2014-07-04 06:07:28</td>
</tr>
</tbody>
</table>
The block happens at $html = str_get_html($table) - if I print out $html, nothing gets printed to the page, not even an error or any kind of 'false' or 'NULL' value. If I try to echo a string after that block of code, it is not output to the page, so the script seems to stop running there.
I was able to confirm that my simple_html_dom.php file is being referenced correctly because echoing a string in that file does get output to my votes-logs-export.php page. Yet the functions within the file don't seem to be firing? I'm out of ideas on this one!
I confirmed that 'allow_url_fopen' is set to 'true' in php.ini. In my simple_html_dom.php file, I also tried changing the "MAX_FILE_SIZE" from 600,000 to 100,000,000 but to no effect. The memory on the server is set to 40MB. I admit I am a newbie with working with custom WordPress plugins, but the fact this works on my localhost seems to indicate there is some kind of configuration or compatibility issue on the live server...? I would appreciate any guidance or tips you can offer.
PHP version on the live server is 5.4.21. My localhost is using 5.3.
I ended up explicitly setting error_reporting(1) in my file, which finally threw me a valuable error - Call to undefined function mb_detect_encoding() on line 1238 of simple_html_dom.php. Turns out I needed to enable the PHP extension mbstring on my server. Problem solved!

Why TCPDF result doesn't show if I have lof of data?

I have developed a software with PHP and report with TCPDF. It runs well, but after importing lot of data in MySQL, the PHP can't produce the report before the browser times out. I've tried with the latest firefox and Chrome versions.
This my script:
<?php
require_once('tcpdf/config/lang/eng.php');
require_once('tcpdf/tcpdf.php');
// create new PDF documentation
include "koneksi.php"; //file conection
$bln=$_POST[BLN]; //for catch month
$thn=$_POST[THN]; //for catch year
$exp=$_POST[EXP]; //for catch expedition name
if(empty($exp))
{
$sql = "SELECT * FROM tb_exp_local where bulan = '$bln' AND tahun = '$thn'";
}
elseif($exp != "")
{
$sql = "SELECT * FROM tb_exp_local where bulan = '$bln' AND tahun = '$thn' AND nama_exp = '$exp'";
}
$hasil = mysql_query($sql);
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
// set font
$pdf->SetFont('times', '', 11);
// landscape
$pdf->addPage( 'L', 'LETTER' );
//this for convert html to pdf with html function
$html = '
<table border="1" cellspacing="3" cellpadding="4">
<tr><td colspan="9" align="center"><h2>Form Pantauan Expedisi Export</h2></td></tr>
<tr>
<th align="center"><b>Tanggal</b></th>
<th align="center"><b>Nama Expedisi</b></th>
<th align="center"><b>Nama Distributor</b></th>
<th align="center"><b>Kota Tujuan</b></th>
<th align="center"><b>No Faktur</b></th>
<th align="center"><b>Kondisi Armada Pengiriman</b></th>
<th align="center"><b>Ketepatan Jumlah</b></th>
<th align="center"><b>Ketepatan Waktu Kirim</b></th>
<th align="center"><b>Keterangan</b></th>
</tr></table>';
while ($data = mysql_fetch_array($hasil))
{
$html .= '<table border="1"><tr><td align="center">'.$data['tgl'].'</td>
<td align="center">'.$data['nama_exp'].'</td>
<td align="center">'.$data['nama_dist'].'</td>
<td align="center">'.$data['kota_tujuan'].'</td>
<td align="center">'.$data['faktur'].'</td>
<td align="center">'.$data['konarmada'].'</td>
<td align="center">'.$data['tepatjml'].'</td>
<td align="center">'.$data['tepatwaktu'].'</td>
<td align="center">'.$data['ket'].'</td>
</tr></table> ';
}
$pdf->writeHTML($html, true, false, true, false, ''); //for generate
$pdf->Output('FormPantauExpLocalAll', 'I'); // for generate pdf file
?>
Server timeout does not depend on browser. Try using set_time_limit(60) inside your loop:
while ($data = mysql_fetch_array($hasil))
{
set_time_limit(60);
$html .= '(...)';
}
Also, try adding INDEX to your DB on (bulan, tahun, nama_exp) columns, it should speed up the retrieval process. Also, be aware that you may have run out of memory during the process (check your PHP logs on your server)

Categories