View pdf report from ajax request - javascript

I have a problem generating a pdf with the TCPDF library, and tried to follow some examples that are here, but I have not managed to solve my problem, which is this: when I click on a button I am making an AJAX request Which sends a parameter and the url points to a controller in php with CODEIGNITER, the parameter is used to execute my query and generate the report based on it. I have already debugged the report with static parameters to see if it worked and without using AJAX, and everything went well. The problem is that I need to send the data this way and I do not know how to load the pdf file created in the response of my request, any ideas?
$("#BtnDownload").click(function (){
var jsonString = 2; //Example parameters;
$.ajax({
type: 'POST',
url: baseurl+"reports/selectReport",
data: {'data': jsonString},
success: function(response){
//What my driver should return
}
});
});
This is the function in my controller that I point my ajax request, I do not put all the code of the layout of my report because it is working, and the code is very long, the important thing is to know how to return my generated report And can view it from the browser.
public function selectReport(){
$this->load->library('Pdf');
$pdf = new Pdf('L', 'mm', 'A4', true, 'UTF-8', false);
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetTitle('report');
$pdf->SetSubject('Report PDF');
$pdf->SetKeywords('TCPDF, PDF, example, test, guide');
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
$pdf->setPrintHeader(false);
$pdf->setFooterData($tc = array(0, 64, 0), $lc = array(0, 64, 128));
$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
$pdf->SetFont('dejavusans', '', 12, '', true);
$base_url = base_url();
$data = $this->input->post("data");
// report body
$name_pdf = utf8_decode("report.pdf");
$pdf->Output($name_pdf, 'I');
}

In TCPDF ( according to TCPDF Save file to folder? ) the PDF can be saved:
$dir = 'pdfs/';
$filename = 'report' . microtime(TRUE) . '.pdf';
if( ! is_dir( FCPATH . $dir ) )
mkdir( FCPATH . $dir, 0777, TRUE );
$pdf->Output( FCPATH . $dir . $filename, 'F'); // F saves to filesystem
Since you know the PDFs are in the pdf directory:
$this->load->helper('url');
echo json_encode(array(
'path' => FCPATH . $dir . $filename,
'url' => base_url( $dir . $filename )
));
Then in your ajax success function data.url is the URL to the file:
success: function(response){
if( response.url ){
window.location = response.url;
}
}
Make sure your $.ajax has the configuration for dataType: 'json'.
$.ajax({
// ...
dataType: 'json'
// ...
});

Related

Trouble sending an generated jsPdf to server

I have generated an PDF using jsPdf and Html2Canvas. It works very well, and is downloadable.
I'm now aiming to get the generated .pdf saved to my server, so I can send it out via phpmailer. This is how I approached this.
function print() {
document.getElementById("out").textContent = document.getElementById("fader").value;
const filename = 'DHC_Herren_Front.pdf';
html2canvas(document.querySelector('#pdf')).then(canvas => {
let pdf = new jsPDF('l', 'mm', 'a4');
pdf.addImage(canvas.toDataURL('image/png'), 'PNG', 0, 0, 298, 211, function () {
var blob = doc.output('blob');
var formData = new FormData();
formData.append('pdf', blob);
$.ajax('/st/tda/dhc/men_front/upload.php', {
method: 'POST',
data: formData,
processData: false,
contentType: false,
success: function (data) {
console.log(data)
},
error: function (data) {
console.log(data)
}
});
});
});
}
and my upload.php
<?php move_uploaded_file(
$_FILES['pdf']['tmp_name'],
$_SERVER['DOCUMENT_ROOT'] . "/st/tda/dhc/men_front/test.pdf");
?>
My Question would be, why I end up without an File on the Server. I feel like there must be an simple solution to this, but I just can't pinpoint it.
Newest HTML
function ma() {
document.getElementById("out").textContent = document.getElementById("fader").value;
html2canvas(document.querySelector('#pdf')).then(canvas => {
var pdf = btoa(doc.output());
pdf.addImage(canvas.toDataURL('image/png'), 'PNG', 0, 0, 298, 211,);
$.ajax({
method: "POST",
url: "/st/tda/dhc/men_front/upload.php",
data: {data: pdf},
}).done(function(data){
console.log(data);
});
});
}
Newest upload.php
<?php
if(!empty($_POST['data'])){
$data = base64_decode($_POST['data']);
// print_r($data);
file_put_contents( "test.pdf", $data );
} else {
echo "No Data Sent";
}
exit();
This is how I do it. Take a look and see if you can adapt it to your code. This is the uploadFiles.php that the ajax sends the file to.
<?php
$ds = DIRECTORY_SEPARATOR; // a directory separator
$cid = $_POST["cid"]; // directory name passed from the form as a variable
$rid = $_POST["rid"]; // directory name passed from the form as a variable
$storeFolder = "../recordFiles/".$cid."/".$rid; // the place where i want to save stuff
// run only if there are files sent from ajax.
if (!empty($_FILES)) {
// check if the directory exists and if not then create it.
if (!file_exists('../recordFiles/'.$cid."/".$rid)) {
mkdir('../recordFiles/'.$cid."/".$rid, 0777, true);
}
// get the temp file name
$tempFile = $_FILES['file']['tmp_name'];
// remove all whitespace in the file name
$cleanedFileName = $_FILES['file']['name'];
$cleanedFileName = preg_replace('/\s+/', '', $cleanedFileName);
// set the target path
$targetPath = dirname( __FILE__ ).$ds.$storeFolder.$ds;
// set the target file name and path
$targetFile = $targetPath.$cleanedFileName;
// move the files
move_uploaded_file($tempFile,$targetFile);
}
?>

Uploading BLOB url to PHP server via ajax - Cordova

I am building a hybrid mobile app with cordova and is using the cordova camera plugin. I was able to get the blob:url for the image but hits a dead-end with uploading it to my back-end php server.
Background information:
I have two buttons that I have created to test the cordova camera api.
1 - Take Photo Btn -> Generates a blob url
2 - Upload Photo -> Suppose to upload the image captured based on the photo take to my server via ajax.
Based on my console, I am getting index:file not found and it generates a 0KB image file on my server. I am fairly new to ajax and blob so would appreciate any assistance rendered.
//JS CODE
uploadimgtoserver : function () {
//x is the blobimage url blob:http://localhost:8000/cb420014-a0b9-481a-b3ea-
6657f7e7c98e
var x = localStorage.getItem('data');
$.ajax({
url: 'URL',
type: 'POST',
data: {'file':x},
success: function (data) {
console.log(data);
},
});
}
};
//php code
$data = $_POST['file'];
$data = str_replace('data:image/jpeg;base64,', '', $data);
$data = str_replace(' ', '+', $data);
$data = base64_decode($data);
$file = uniqid() . '.jpg';
$success = file_put_contents($file, $data);

Generate and download CSV file with php and ajax

I have a php page that creates a CSV file that is then downloaded by the browser automatically. Here is a version with sample data - it works great.
<?php
$cars = array(
array("Volvo",22,18),
array("BMW",15,13),
array("Saab",5,2),
array("Land Rover",17,15)
);
// output headers so that the file is downloaded rather than displayed
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=csvfile.csv');
// create a file pointer connected to the output stream
$output = fopen('php://output', 'w');
// output the column headings
fputcsv($output, array('Car', 'Year', 'Miles' ));
//Loop through the array and add to the csv
foreach ($cars as $row) {
fputcsv($output, $row);
}
?>
I would like to be able to run this from another page using ajax so that a user can generate/download a csv without leaving the main page. This is the JavaScript I am using on the main page. In my real page I am using the data coming via ajax.
$('button[name="exportCSVButton"]').on('click', function() {
console.log('click');
$.ajax({
url: 'exportCSV.php',
type: 'post',
dataType: 'html',
data: {
Year: $('input[name="exportYear"]').val()
},
success: function(data) {
var result = data
console.log(result);
}
});
});
When I click the button to trigger the script, it runs, but instead of saving/download to csv it prints the entire thing to console. Is there any way to accomplish what I want? Without actually saving the file to the server and reopening.
I have done csv file download via ajax
PHP Code
<?php
function outputCsv( $assocDataArray ) {
if ( !empty( $assocDataArray ) ):
$fp = fopen( 'php://output', 'w' );
fputcsv( $fp, array_keys( reset($assocDataArray) ) );
foreach ( $assocDataArray AS $values ):
fputcsv( $fp, $values );
endforeach;
fclose( $fp );
endif;
exit();
}
function generateCsv(){
$res_prods = $wpdb->get_results( "SELECT * FROM `{$wpdb->prefix}products` ", OBJECT );
$products= [];
foreach ($res_prods as $key => $product) :
$product_id = $product->ID;
$products[$product_id]['product_id'] = $product_id;
$products[$product_id]['name'] = $product->name;
endforeach;
return outputCsv( $products);
}
jQuery AJAX
jQuery(document).on( 'click', '.btn_generate_product', function(e) {
var product_id = jQuery(this).data('product_id');
jQuery.ajax({
url : "ajaxurl",
type: 'POST',
data: { product_id },
success: function(data){
/*
* Make CSV downloadable
*/
var downloadLink = document.createElement("a");
var fileData = ['\ufeff'+data];
var blobObject = new Blob(fileData,{
type: "text/csv;charset=utf-8;"
});
var url = URL.createObjectURL(blobObject);
downloadLink.href = url;
downloadLink.download = "products.csv";
/*
* Actually download CSV
*/
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
}
});
});
Replace console.log(result); with file save code.
check here JavaScript: Create and save file
The best way to save file with browser dialog box, use simple code.
<a href="#" onclick="window.open('exportCSV.php?year=' + $('input[name="exportYear"]').val())" >Download File</a>
I did it time ago by creating a hidden iframe and via javascript the source of the iframe was set to a php file which sent the appropriate headers and data as your exportCSV.php does.
But, if you don't like this idea, you could use a library like jQuery File Download or FileSaver.js

How do I send a Blob of type octet/stream to server using AJAX?

I have unsuccessfully been trying to send a Blob file (which is an .OBJ file type) to the server using AJAX. I want to be able to do this without using an input file field. I am making an online avatar creator, so the Blob file to be sent to the server is generated from the character that is initially imported into my Three.js scene. I have been able to send a Blob file that contains a String to the server and save this to a specified folder (which I am aiming to do with the Blob .OBJ file). I have tried converting the Blob to Base64 before sending it in a POST request, but this did not work. The size of the file that I am trying to send is 3MB.
Here is my JavaScript code for creating the Blob file and sending it to my PHP script on the server using AJAX.
//Create OBJ
var exporter = new THREE.OBJExporter();
var result = exporter.parse(child);
//Generate file to send to server
var formData = new FormData();
var characterBlob = new Blob([result], {type: "octet/stream"});
var reader = new FileReader();
reader.readAsDataURL(characterBlob);
reader.onloadend = function() {
formData.append('file', reader.result);
$.ajax({
url: "ExecuteMaya.php", // Url to which the request is send
type: "POST", // Type of request to be send, called as method
data: formData, // Data sent to server, a set of key/value pairs (i.e. form fields and values)
processData:false, // To send DOMDocument or non processed data file it is set to false
contentType: false, // The content type used when sending data to the server
}).done(function(data) {
console.log(data);
});
}
Here is my PHP script for handling the sent file.
<?php
$sourcePath = $_FILES['file']['tmp_name']; // Storing source path of the file in a variable
$targetPath = "upload/".$_FILES['file']['name']; // Target path where file is to be stored
move_uploaded_file($sourcePath,$targetPath) ; // Moving Uploaded file
echo "<span id='success'>Image Uploaded Successfully...!!</span><br/>";
echo "<br/><b>File Name:</b> " . $_FILES["file"]["name"] . "<br>";
echo "<b>Type:</b> " . $_FILES["file"]["type"] . "<br>";
echo "<b>Size:</b> " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
echo "<b>Temp file:</b> " . $_FILES["file"]["tmp_name"] . "<br>";
?>
Any help would be much appreciated!
UPDATE 1: The var result = exporter.parse(child); is a String and whenever I print this variable to the console it takes a few minutes to load. Would the size of this String be a possible issue with trying to send it to the server?
UPDATE 2: This gets printed to the console after the PHP script has been executed, which makes me think that either nothing is being sent over to the server or the sent data is not being handled correctly by the PHP script.
Image Uploaded Successfully...!!File Name: Type: Size: 0 kBTemp file:
UPDATE 3: Here is a link to the file that I am trying to send.
http://www.filehosting.org/file/details/578744/CleanFemaleOBJ.obj
You can view this file in TextEdit/NotePad to view the String that I want to send. It is pretty much a text file with the .obj extension to convert it to that format so it can be opened in Maya.
UPDATE 4: I have now altered my JavaScript code so that the Blob is appended to the FormData and not the result of reader.readAsDataURL(characterBlob).
//Create OBJ
var exporter = new THREE.OBJExporter();
var result = exporter.parse(child);
//Generate file to send to server
var formData = new FormData();
var characterBlob = new Blob([result], {type: "octet/stream"});
formData.append('file', result);
$.ajax({
url: "ExecuteMaya.php", // Url to which the request is send
type: "POST", // Type of request to be send, called as method
data: formData, // Data sent to server, a set of key/value pairs (i.e. form fields and values)
processData: false, // To send DOMDocument or non processed data file it is set to false
}).done(function(data) {
console.log(data);
});
Using the following code, I was able to upload the .obj file.
I had to increase my maximum upload size for it to work.
You may also think of increasing your maximum execution time as commented below, but I didn't have to.
For simplicity, I put everything in one file called form.php.
form.php
<?php
// good idea to turn on errors during development
error_reporting(E_ALL);
ini_set('display_errors', 1);
// ini_set('max_execution_time', 300);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
echo "<br/><b>File Name:</b> " . $_FILES["file"]["name"] . "<br>";
echo "<b>Type:</b> " . $_FILES["file"]["type"] . "<br>";
echo "<b>Size:</b> " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
echo "<b>Temp file:</b> " . $_FILES["file"]["tmp_name"] . "<br>";
echo "<b>Error:</b> " . $_FILES["file"]["error"] . "<br>";
$sourcePath = $_FILES['file']['tmp_name']; // Storing source path of the file in a variable
$targetPath = "uploads/" . $_FILES['file']['name']; // Target path where file is to be stored
if (move_uploaded_file($sourcePath, $targetPath)) { // Moving Uploaded file
echo "<span id='success'>Image Uploaded Successfully...!!</span><br/>";
} else {
echo "<span id='success'>Image was not Uploaded</span><br/>";
}
exit;
}
?>
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
</head>
<body>
<form action="form.php" method="post" enctype="multipart/form-data">
<label>File</label>
<input type="file" name="file">
<input type="submit" value="Upload">
</form>
<div></div>
</body>
<script>
$(function () {
$('form').on('submit', function (e) {
e.preventDefault();
// logic
$.ajax({
url: this.action,
type: this.method,
data: new FormData(this), // important
processData: false, // important
contentType: false, // important
success: function (res) {
$('div').html(res);
}
});
});
});
</script>
</html>
So, first test to see if you can upload the .obj file using the code above.
As you are testing it out, have your browser's developer tool open. Monitor your Network/XHR tab [Chrome, Firefox] to see the request that gets made when you click Upload.
If it works, try using the same logic in your original code.
var formData = new FormData();
formData.append('file', result);
$.ajax({
url: "ExecuteMaya.php",
type: "post",
data: formData, // important
processData: false, // important
contentType: false, // important!
success: function (res) {
console.log(res);
}
});
Again, monitor the request made in your Network/XHR tab and look at what is being sent.

Ajax call using php file placed in theme folder in Osclass classified script?

I am using Osclass classified script, trying to alert a message returned by ajax call.
My ajax-test.php file which is saved in my theme folder contains
<?php
$name = $_GET["name"];
echo "I am " . $name
?>
and my JavaScript function code is
function findName() {
var name = "Jhon";
$.ajax({
method: "POST",
// url: "oc-content/themes/bender/ajax-test.php",
url: 'http://127.0.0.1/osclass/index.php?page=ajax&action=custom&ajaxfile=ajax-test.php',
data: { name : name },
success: function (data) {
alert(data);
},
})
}
Anybody tell me what am I doing wrong? it alerts
{"error" => "ajaxFile doesn't exist"}
Note: It works fine with commented line of code
You are using
> method: "POST",
in ajax then why are you using GET ?
$name = $_GET["name"];
Using Post to getting value for it.
$name = $_POST["name"];
Unfortunatelyn, that's not exactly how the ajax.php custom action works.
First, page=ajax&action=custom doesn't work with themes, only with plugins since it will search ajaxfile inside the plugins folder by doing something like this:
$filePath = osc_plugins_path() . $ajaxfile; // eg. /oc-content/plugins/$ajaxfile
You then have to pass in ajaxfile the name of the plugin to work. If you were using the Madhouse Messenger plugin, you would do something like:
page=ajax&action=custom&ajaxfile=madhouse_messenger/main.php
However, since 3.3, when using page=ajax&action=custom, you do not use the ajaxfile param anymore but the route param. You can take a look at how routes work here and some examples of routes here.
in your theme functions.php
add something like this:
//name of your custom ajax request
$my_custom_ajax_request_name = 'doSomethingCool';
osc_add_hook('ajax_' . $my_custom_ajax_request_name, $my_custom_ajax_request_name);
function doSomethingCool()
{
// set default response
$response = [
'status' => false,
'msg' => 'Default Error Message...',
];
// token protection
// read more about csrf token:
// https://dev.osclass.org/2013/02/19/make-your-plugins-more-secure-with-anti-csrf-functions/
osc_csrf_check();
// get request parameters
$param1 = Params::getParam('param1');
$param2 = Params::getParam('param2');
// do some logic here ex: check if user is logged in
if (osc_is_web_user_logged_in()) {
$response['status'] = true;
$response['msg'] = 'User is logged in. ;-) ' . $param1 . ' ' . $param2 . '! ' . osc_logged_user_name();
} else {
$response['status'] = false;
$response['msg'] = 'User is not logged in. :-(';
}
// return json response
header('Content-Type: application/json');
echo json_encode($response);
exit;
}
some where in your template files like header.php, footer.php or everything else you need it...
<a data-param1="hello" data-param2="world" href="#" id="make-an-ajax-request">
Make an AJAX Request!
</a>
<script>
//here we hold some usefull info for easy access
var mySite = window.mySite || {};
mySite.base_url = '<?php echo osc_base_url(true); ?>';
mySite.csrf_token = '<?php echo osc_csrf_token_url(); ?>';
$(function(){
$('#make-an-ajax-request').on('click', function(e){
e.preventDefault();
// name of our custom ajax hook
var ajax_hook = 'doSomethingCool';
// get parameters
var param1 = $(this).data('param1');
var param2 = $(this).data('param2');
// build axjxa url
var url = mySite.base_url + '?page=ajax&action=runhook&hook='+ajax_hook+'&'+mySite.csrf_token;
//build data
var data = {
param1 : param1,
param2 : param2
};
$.ajax({
type: 'POST',
dataType: 'json',
data: data,
url: url
}).done(function (data) {
console.log(data);
if (data.status) {
} else {
}
});
});
});
</script>
OSCLASS WAY
to note that the current osclass way of doing an ajax request from a theme page is to call the
http://example.com/?page=ajax&action=runhook&hook=MY_HOOK_FUNCTION_NAME
and register it like osc_add_hook('ajax_MY_HOOK_FUNCTION_NAME',
'MY_HOOK_FUNCTION_NAME'); optionally but very recommended is the use
of the csrf token that you can implement like i have done for url or
by calling the osc_csrf_token_form() directly into your form.
NON OSCLASS WAY
just create a file in your theme or everywhere you want and make sure to put this into it <?php require_once __DIR__ . RELATIVE_PATH_TO_OC_LOAD_FILE . 'oc-load.php'; ?> then build your logic into it.

Categories