How do you save a PDF with FDPF using parameters? - php

I have this button, that is tied to this function:
$('#genPDF').click(function () {
var str = "hText=something" +
"&cText=also something";
$.ajax({
url: "/wp-content/themes/mytheme/indexpdf.php",
data: str,
cache: false,
success: function (result) {
console.log("Success!");
$("#pdfobject").attr("src", "/wp-content/themes/mytheme/flyer.pdf");
var container = document.getElementById("pdfContainer");
var content = container.innerHTML;
container.innerHTML = content;
}
});
});
To explain what the successful ajax code does, first outputs "success!" in the console, which the browser does, then replaces a certain div on the page with a revised link (refreshing a certain part of the page).
This above code works, and makes it's way over to indexpdf.php, which is:
<?php
$hText = trim(isset($_GET['hText']) ? $_GET['hText'] : '');
$cText = trim(isset($_GET['cText']) ? $_GET['cText'] : '');
require_once('fpdf.php');
require_once('fpdi.php');
// initiate FPDI
$pdf = new FPDI();
$pdf->AddPage();
$pdf->setSourceFile("TestFlyer.pdf");
$tplIdx = $pdf->importPage(1);
$pdf->useTemplate($tplIdx, 10, 10, 100);
$pdf->SetFont('Helvetica');
$pdf->SetTextColor(255, 0, 0);
$pdf->SetXY(30, 30);
$pdf->Write(0, $hText.$cText);
$pdf->Output("D","flyer.pdf");
?>
The problem is, it's supposed to take testflyer.pdf, load it's first page and write my passed in arguments into it. THEN, save itself as flyer.pdf.
It's not saving, I don't know what's doing on or what the problem is.
All PDF's and PHP files above are in the /mytheme/ folder.

If you want to save the PDF, set the dest parameter as F:
So,
$pdf->Output("D","flyer.pdf");
must be:
$pdf->Output("F","flyer.pdf");
And reformat your write line as:
$pdf->Write(0, "$hText $cText");
According to the documentation, destination where to send the document. It can be one of the following:
I: send the file inline to the browser. The PDF viewer is used if available.
D: send to the browser and force a file download with the name given by name.
F: save to a local file with the name given by name (may include a path).
S: return the document as a string.
The default value is I.

Related

FPDF error while creating class

I've a problem with creation af the class needed for outputting JSON data to PDF. The PHP file is as following:
<?php
header('Content-type: text/json');
ob_start();
require('fpdf.php');
class PDF extends FPDF{
// Colored table
function FancyTable($PDFtabHead, $PDFtabData)
{
// stuff with table works if tested with another PHP page
}
} // END -class
$PDFtabHead = json_decode(($_POST['PDFtabHead']), true);
$PDFtabData = json_decode(($_POST['PDFtabData']), true);
$pdf = new PDF();
$pdf->SetFont('Arial','',12);
$pdf->AddPage();
$pdf->FancyTable($PDFtabHead,$PDFtabData);
$pdf->Output();
echo json_encode(array("res"=>$PDFtabHead)); // Only to chek if outputs something
ob_end_flush();
?>
The caller function from my JS file is:
$.ajax({
type: "POST",
async: false,
url: './FPDF/PDF.php',
dataType: 'json',
data: {PDFtabHead: tabHead, PDFtabData: tabData},
success: function (response) {
var res = response.res;
console.log("ok return: "+res);
} // success
,
error: function() {
console.log("ERROR CONNECTING TO ./FPDF/PDF.php");
}// error
}); // ajax
tabHead and tabData are correct, this is the output of tabData :
["05:22","0043","22:31","200201","05:22","0044","22:31", ......]
The call to PDF.php always ends with error, outputting to console : ERROR CONNECTING TO ./FPDF/PDF.php
If I test it from another test page that doesn't send data in JSON format, but a normal PHP Array it works. Obviously I have to change to
$PDFtabHead = ($_POST['PDFtabHead']);
$PDFtabData = ($_POST['PDFtabData']);
in this case PDF page is rendered correctly.
Similarly if I delete the class declaration, and simply return back to my JS page the JSON array, it works; doesn't print PDF it's clear but the Array is returned as expected
OK I've got the solution at the FPDF forum
http://www.fpdf.org/?go=forum&i=56364&t=56363, Oliver's answer is
Don't return a PDF from an AJAX call.

PHP - return image with header("X-sendfile") returns null on first iteration, binary on second (using ajax)

Okay. I have a gallery-app I'm building, where I have a list of thumbnails, and when clicked, fetches the original image via an ajax-call to a showfile.php which just returns the file via header() using X-Sendfile. This works, but for some reason I can't get a subsequent call to return the correct values, and the script breaks. (First return returns "null", which is what I want, while second returns the image as binary data).
Okay.
Here's the code for the ajax-call:
$('.lightbox').click(function(e) {
e.preventDefault();
var $this = $(this);
var linkName = $(this).attr('href').split('=')[1];
$.ajax({
url: 'showfile.php',
type: 'GET',
dataType: 'binary',
data: 'file='+linkName+'',
responseType: 'blob',
processData: false,
success: function(result) {
var image = new Image();
image.src = URL.createObjectURL(result);
$('#lightbox_container').append(image).removeClass('hidden').addClass('visible');
image.onload = function() { var imageWidth = image.width/2; $('#lightbox_container').css({'margin-left':'-'+imageWidth+'px'}); window.URL.revokeObjectURL(image.src);};
$('#overlay').removeClass('hidden').addClass('visible');
$('.nextbutton,.prevbutton').click(function(e) {
if ($(e.target).hasClass('prevbutton')) {
var linkName = $this.parent('.pictures').prev('li.pictures').find('a').attr('href').split('=')[1];
$.ajax({
url: 'showfile.php',
type: 'GET',
datatype: 'binary',
data: 'file='+linkName+'',
responseType: 'blob',
processData: false,
success: function(result2) {
var image = new Image();
var binaryData = [];
binaryData.push(result2);
image.src = URL.createObjectURL(new Blob(binaryData));
// image.src = URL.createObjectURL(result2);
$('#lightbox_container img').remove();
$('#lightbox_container').append(image);
image.onload = function() { var imageWidth = image.width/2; $('#lightbox_container').css({'margin-left':'-'+imageWidth+'px'}); };
}
})
}
})
}
});
});
This works, up until the second ajax-call - the return value from showfile.php on the second call is a binary block (if I look at the NET-tab in console, I get the correct image returned), but for some reason the createObjectUrl doesn't work (I've tried without the binaryData-bit, but then the createObjectUrl just fails, naturally, since the result isn't correct for the usage.
The showfile.php is as follows:
<?php
require_once('conf/config.php');
if (!session_id()) { session_start(); };
if ($isloggedin) {
if (isset($_GET['file'])) {
// $getFile = readfile($_SERVER['DOCUMENT_ROOT'].'/'.$userpath.$username.'pictures/'.$_GET['file']);
header('Content-type: image/jpeg');
header('X-Sendfile: '.$_SERVER['DOCUMENT_ROOT'].'/'.$userpath.$username.'pictures/'.$_GET['file'].''); # make sure $file is the full path, not relative
exit;
// echo base64_encode($getFile);
}
}
?>
There are some commented lines, I was trying using readfile() instead, doesn't work any better, just seems a bit slower in general.
So, what I'm after is: what am I doing wrong? As the ajax-call works on first click, it should work on second click as well, right? But it doesn't. However, if I close the image down, and click a new thumbnail, it works just fine. No refresh of the page or anything like that, just close the popup, and click a new thumbnail, it works again. But for some reason, it doesn't return the same "null" value on second click.
Which leads me to believe that there is something not being closed or reset or whatever, and some sort of "left over" issue - which leads me to the php-file, since that is what seems to return different values. Is there anything there I can do to "zero out"?
I've tried Googling, but haven't really found that much information about these functions at all.
Oh, the second ajax-click returns, as I said, some binary information - but when I try to create an objectUrl from it, using blob, it doesn't work - ie, the url doesn't work, it just shows a broken image icon, not the actual image, although the url seems correct (same url as if I revisit the thumbnails and click again, starting over), and as I said, the net-tab in console shows the image being returned in both cases.
Okay, I feel incredibly stupid now. It's a typo. The datatype should be dataType- sometimes the camel-case in javascript trips me up. Changing that fixes the issue.

Upload Image using ajax (json)

I need to upload image using ajax. Elaborating my point:
I need to pass my image data to a PHP page and check the type, size, name and all other attributes of the file. If all attributes matches, then only I need to transfer the file. Problem here is passing of data should be done in JSON(AJAX) format only. One more important thing is that I don't have to convert it to base64.
If you can help me in this, You are most welcome.
Thanks in advance.
The idea in SO is to work on the OP current code. I mean, we are not here to make all the job, because it should have a price. Anyway, here is a workaround for your issue:
Convert your image to base64 using javascript. This useful method works like a charm:
// Code taken from MatthewCrumley (http://stackoverflow.com/a/934925/298479)
function getBase64Image(img) {
// Create an empty canvas element
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
// Copy the image contents to the canvas
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
// Get the data-URL formatted image
// Firefox supports PNG and JPEG. You could check img.src to guess the
// original format, but be aware the using "image/jpg" will re-encode the image.
var dataURL = canvas.toDataURL("image/png");
return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
}
Then just pass the returned string as base64 through ajax:
$.ajax({
url: 'path/to/your/script.php',
type: 'post',
data: { paramName: imagedata } // the returned data from above js method,
/*...*/
});
And, in PHP side, just return the string to an image file:
// Code taken from Austin Brunkhorst (http://stackoverflow.com/a/15153931/3648578)
function base64_to_jpeg($base64_string, $output_file) {
$ifp = fopen($output_file, "wb");
$data = explode(',', $base64_string);
fwrite($ifp, base64_decode($data[1]));
fclose($ifp);
return $output_file;
}

Using PHP DOMPDF and AJAX to download a PDF File

I have this PHP File called print.php:
<?php
require_once("modules/pdf/dompdf_config.inc.php");
$html = $_POST["toRender"];
$number = $_POST["number"];
$dompdf = new DOMPDF();
$dompdf->load_html($html);
$dompdf->render();
$dompdf->stream($number.".pdf");
As you can see, the HTML and a Number are received via POST.
The JavaScript file looks like this:
$("#btnViewPDF").click(function() {
var theHtml = $("#printable").html();
var theNumber = $("#invoiceNumber").val();
$.ajax({
type : "post",
url : "views/print.php",
data : {toRender : theHtml, number : theNumber},
beforeSend: function() {
$(".ajax-loader-bg").fadeIn();
}
}).always(function() {
$(".ajax-loader-bg").fadeOut();
});
return false;
});
Basically it takes all the content inside a DIV called 'printable' but what I want next is the PDF that has been generated in print.php to be displayed, I haven't been able to figure out how can I make this.
I've made it work when I generate test HTML inside print.php and then I type in the url mysite.com/print.php ... it renders the PDF and allows me to download it or see it in another browser tab.
How can I achieve this via AJAX?
You can't download something via AJAX, you could simulate the behavior using an hidden iframe.
Not that you can't download it, but, it will never end up in the filesystem for saving purpose because javascript can't do that for security reasons.
Anyway people always find solutions, you can try this: https://stackoverflow.com/a/23797348/1131176
i did achieve this, by doing just a trick, this example is made in codeigniter, so you can adapt it, first, the ajax method:
$.ajax({
url: base_url+"controladorapr/exportComprobanteIngresos", //method i called
data: $(this).serialize() //i serialized data from a form,
type:"POST",
dataType: 'JSON',
success: function (data) {
//create a link to download the pdf file
var link=document.createElement('a');
//i used the base url to target a file on mi proyect folder
link.href=window.URL = base_url+"exportacion.pdf";
//download the name with a different name given in the php method
link.download=data.nombre_archivo;
link.click();
//this js function hides the loading gif i use
hideLoad();
}
});
Now, let's head to the method on my controller:
function exportComprobanteIngresos(){
//receive your ajax data
$fecha = $this->input->post("fecha_comprobante_ingresos");
$fecha = date_format(DateTime::createFromFormat('d/m/Y', $fecha), "Y-m-d");
//send data to pdf
$data["fecha"] = $fecha;
//do some query here to send data and save it into $data[] array
//pdf size
$tamaño = 'A4';
//create a file name
$nombre_archivo = "Comprobante_ingresos".date_format(DateTime::createFromFormat('Y-m-d', $fecha), "Y_m_d").".pdf";
//load dompdf method, i will show this later, and send the data from db and file name
$pdf = $this->pdf->load_view("pdf/comprobanteIngresos", $data, $tamaño, $nombre_archivo);
//save the pdf content into the file we are downloading
file_put_contents('exportacion.pdf', $pdf);
//send data back to javascript
$data2["nombre_archivo"] = $nombre_archivo;
echo json_encode($data2);
}
now, we will include dompdf, to use dompdf on codeigniter see this answer: Codeigniter with dompdf
Now, this is the code from dompdf i use in the function '$this->pdf->load_view':
$dompdf = new Dompdf();
$html = $this->ci()->load->view($view, $data, TRUE);
$dompdf->loadHtml($html);
// (Optional) Setup the paper size and orientation
$dompdf->setPaper($size, 'portrait');
// Render the HTML as PDF
$dompdf->render();
// Output the generated PDF to variable and return it to save it into the file
$output = $dompdf->output();
return $output;
now with this, i managed to use ajax with dompdf and put a loading gif to it, and it works great, by last, the php file you load on '$this->pdf->load_view' doesn't have a header or else, is pure html and php, hope this helps!

PHPExcel showing garbage in main page

I need to generate a PDF file with some information i get from a database, i'm using PHPExcel in order to do this, but here is the thing, when i click the button `report` so i get all the information and put it into the PDF, i get a lot of "garbage" in my page, this garbage it's like when you try to open a PDF with notepad and it just shows random symbols.
Here is how i do it
I'm using an $.ajax call to get all the information displayed into a form:
$.ajax({
// gets all the information and puts them into the form and several tables
});
Then i add an event handler to the button report so that i send the request id to a php script which will gather the necessary information to fill the report
report.on('click',function(){
$.ajax({
url : '../../php/reports/requestReport.php',
type : 'post',
data : {'idRequest' : id },
dataType : 'json',
success : function(response){
console.log(response);
},
error : function(response){
if(response.responseText != undefined)
$('body').append(response.responseText);
console.warn(response);
}
});
});
And on my php file i have something like this:
<?php
require '../functions.php';
require '../classes/PHPExcel.php';
if(isset($_POST['idRequest']))
$idRequest = $_POST['idRequest'];
else{
$idRequest = false;
echo json_encode(array("ExitCode"=>1,"Message"=>"idRequest Not Received","Location"=>"requestReport.php"));
}
if($idRequest){
try{
// get all the data
// save the request and send it to the report
$excel = new PHPExcel();
//Initializing
$excel->getProperties()->setCreator("TTMS")
->setLastModifiedBy("TTMS")
->setTitle("Request update $idRequest");
$excel->setActiveSheetIndex(0)
->setCellValue('C1', 'Request For Q.A. / Q.C. / Testing');
// Rename worksheet
$excel->getActiveSheet()->setTitle("$idRequest");
// Set active sheet index to the first sheet, so Excel opens this as the first sheet
$excel->setActiveSheetIndex(0);
// Redirect output to a client’s web browser (PDF)
header('Content-Type: application/pdf');
header('Content-Disposition: attachment;filename="Update_Request_'.$idRequest.'.pdf"');
header('Cache-Control: max-age=0');
$objWriter = PHPExcel_IOFactory::createWriter($excel, 'PDF');
$objWriter->save('php://output');
} catch(PDOException $ex){
echo json_encode(array("ExitCode"=>2,"Message"=>$ex->getMessage(),"Location"=>"requestReport.php PDOException"));
}
So long story short i get garbage on the page where the form is. I think it has something to do with the fact that i'm doing this via ajax but i need to do this so the echo's i have to report the errors in my code.
You're writing the PDF output inside an existing HTML page
$('body').append(response.responseText);
The browser assumes everything displayed in an HTML page is HTML markup, not a stream of binary data.
Direct the output to a new browser window if success.
Write all the output to an HTML file, then use wkhtmltopdf -> http://code.google.com/p/wkhtmltopdf/ to convert it to PDF. It works awesome!
Here is code you would use to create your html file:
if (!$handle = fopen('/path/to/folder/your_file.html', 'w')) {
die("Cannot open file for write");
}
$data_string = "<html><body></body></html>"; //all your html output goes here, formatted correctly, etc
// Write somecontent to our opened file.
if (fwrite($handle, $data_string) === FALSE) {
die("Cannot write to file");
}
Then once that is successful you convert it to PDF, then remove the old html file
// convert to PDF
$output = shell_exec('wkhtmltopdf --page-size Letter /path/to/folder/your_file.html /path/to/folder/your_file.pdf');
if (strpos($output,'Error') == false){
$output = shell_exec('rm /path/to/folder/your_file.html');
}else{
die("error creating pdf, please contact IT administrator.");
}
Now you have the PDF sitting in the location -> /path/to/folder/your_file.pdf which you can make the user download.

Categories