This question already has answers here:
Download CSV file using "AJAX"
(6 answers)
Closed 3 years ago.
I have the following problem:
I'm upgrading a working system, so I have to create code that fits in.
I want to create a csv file on a php page and a mysql database. I'm also using Ajax to stay on the same page while running other php-Files. Here are the Code snippets:
PHP/HTML-Page with Button
<div class="btn" id="export">Export</div>
Javascript Ajax
$("#export").click(function() {exportInfos();});
function exportInfos() {
$.ajax({
type: "POST",
url: "functions/exportInfos.php",
data: { searchterm: $("#search").val(), filterbycat: $("#filterbycat").val(), filterbytype: $("#filterbytype").val()},
success: function(response){
console.log("success_export");
},
});
}
PHP-File to create csv(exportInfos.php):
<?php
include ('../../config.php');
$searchterm = $_POST["searchterm"];
$filterbycat = $_POST["filterbycat"];
$filterbytype = $_POST["filterbytype"];
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename=export.csv');
$output = fopen("php://output", "w");
$query = "SELECT * FROM database";
$result = mysqli_query($mysqli, $query);
while($row = mysqli_fetch_assoc($result))
{
fputcsv($output, $row);
}
fclose($output);
?>
I'm not sure where the Problem is but in the console I only see that the php script is called and the success_export text from the log, but no file is opened or downloadable. I think the problem could be with the AJAX part because thats the part Im not sure about the most.
The data values in the Ajax part are there to edit the query as soon as i get some output File.
$mysqli is the connection defined in the config file.
I think you need the change download methodology. Maybe it can be as follows.
Static Page :
<!doctype html>
<html lang="en">
<body>
<div class="btn" id="export">Export</div>
</body>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
$('#export').click(function() {exportInfos();});
function exportInfos() {
$.ajax({
type: 'POST',
url: 'functions/createCSV.php',
data: {
searchterm: $('#search').val(),
filterbycat: $('#filterbycat').val(),
filterbytype: $('#filterbytype').val(),
},
success: function(response) {
if (response.filename != undefined && response.filename.length > 0) {
window.open('functions/downloadCSV.php?filename='+response.filename);
}
},
});
}
</script>
</html>
createCSV :
<?php
include('../../config.php');
$searchterm = $_POST["searchterm"];
$filterbycat = $_POST["filterbycat"];
$filterbytype = $_POST["filterbytype"];
//header('Content-Type: text/csv');
//header('Content-Disposition: attachment; filename=export.csv');
$outputPath = '/path/to/save/outputFile.csv';
$output = fopen($outputPath, "w");
$query = "SELECT * FROM database";
$result = mysqli_query($mysqli, $query);
while ($row = mysqli_fetch_assoc($result)) {
fputcsv($output, $row);
}
fclose($output);
header('Content-Type: application/json');
echo json_encode(
[
"filename" => basename($outputPath),
]
);
downloadCSV :
<?php
if (!empty($_GET['filename'])) {
http_send_status(404);
}
$filepath = "/path/to/save/" . $_GET['filename'];
if (!is_file($filepath) || !is_readable($filepath)) {
http_send_status(404);
}
header("Content-Type: text/csv");
header("Content-Disposition: attachment; filename=" . $_GET['filename']);
echo file_get_contents($filepath);
Related
I want to generate a csv file with a dynamic filename which came from the values I got using an ajax jquery request. These values will be used as filename for my generated csv file. My program does not generate the csv file. What should I do for the csv file to be generated?
I am a newbie when it comes to php and especially AJAX and Jquery so I am still a bit confused on how an AJAX request works.
I'm using a free trial version of Sublime IDE and localhost for php. The program displays the contents of the csv file through an alert box but it doesn't generate a csv file.
This is my jquery ajax request file:
var selectedLanguage = $('#selectLanguage').val();
var length;
length = selectedLanguage.length;
for (var i = 0; i < length; i++)
{
var selectedLanguage = $('#selectLanguage').val();
$.ajax({
crossDomain: true,
async: false,
url: "downloadFile.php",
type: "GET",
data: {"seLang": selectedLanguage[i]},
success: function(data)
{
alert(data);
location.reload();
}
});
}
This is my downloadFile.php code:
<?php
$id="";
if(isset($_GET['seLang'])){
$id = $_GET['seLang'];
$filename = "File_".$id.".csv";
$f = fopen('php://memory', 'w');
//set headers for column
$fields = array('Content1', 'Content2', 'Content3','Content4');
fputcsv($f, $fields, ',');
fseek($f, 0);
header('Content-Encoding: UTF-8');
header('Content-type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename="' . $filename . '";');
fpassthru($f);
}
else
{
echo "<script type='text/javascript'>alert('Empty');</script>";
}
?>
Edit 1:
Thank you Prvn and Sunday Johnson for trying to help. Although, I've found the actual problem. I've read from another post in this site that it is isn't possible to download the generated csv file using AJAX. What else can I do for me to download a csv file?
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="sample.csv"');
$fields = array('Content1', 'Content2', 'Content3','Content4');
$fp = fopen('php://output', 'wb');
foreach ( $fields as $line ) {
$val = explode(",", $line);
fputcsv($fp, $val);
}
fclose($fp);
Output
One comment about the Ajax code, why are you iterating over the value?
About the php code, use this instead:
<?php
$id="";
if(isset($_GET['seLang'])){
$id = $_GET['seLang'];
$filename = "File_".$id.".csv";
$f = fopen($filename, 'w');
//set headers for column
$fields = array('Content1', 'Content2', 'Content3','Content4');
fputcsv($f, $fields, ',');
fclose($f);
}
else
{
echo "<script type='text/javascript'>alert('Empty');</script>";
}
?>
I have a PHP file which is querying a MySQL database in order to return results, I'm currently saving the relevant result row into a PHP array and I'm then trying to echo out a JS array with the PHP data stored. I do not seem to be able to access the JS variable from my JS files.
PHP:
while($row = mysqli_fetch_array($query)) {
$dataArray = array($row['stepNumber']);
echo '<script>';
echo 'var dataArray = ' . json_encode($dataArray) . ';';
echo '</script>';
}
JS:
$.ajax({
type: 'POST',
url: 'queries/dateRangeSelect.php',
dataType: 'text',
data: {startDate: startDate, endDate: endDate},
cache: false,
success: function(response) {
console.log(response);
window.alert(dataArray);
},
dataArray is being reported as not defined when the window.alert tries to trigger.
EDIT:
while($row = mysqli_fetch_array($query)) {
$dataArray = array($row['stepNumber']);
}
header('Content-Type: application/json');
echo $dataArray;
It is no longer printing errors but the console is now not printing anything.
Don't return a <script> tag, you can just return the JSON:
header('Content-Type: application/json');
echo $json;
You probably want to do this AFTER your loop is complete and you have built up the array you wish to return.
UPDATE
Based on your edit, I suggest something more like this:
$dataArray= [];
while($row = mysqli_fetch_array($query)) {
$dataArray[] = array($row['stepNumber']);
}
header('Content-Type: application/json');
echo json_encode($dataArray);
I have a webpage that displays a list of my local files, and I have a search bar that goes through the list of files and highlights the first match.
However, how can I display the files only when a user searches for a filename. So instead of all the files showing, I'd only like the files that match the search criteria to be returned.
PHP, JavaScript, jQuery is totally an option here if anyone can help in that area.
testexec.php:
<?php
$path = '/var/www/html/'; //get list of files
$files = scandir($path);
//display the links
foreach($files as $file) {
if($file != '.' && $file != '..') {
echo '<div> '.$file.'</div>';
}
}
?>
readfile.php:
<?php
// PHP script to allow the file to be downloaded
$filename = $_GET['file'];
if (file_exists($filename)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment;
filename="'.basename($filename).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($filename);
exit;
}
?>
//JavaScript for searchbar
function FindNext() {
var str = document.getElementById ("livesearch").value;
if (str == "") {
alert ("Please enter some text to search!");
return;
}
var supported = false;
var found = false;
if (window.find) { // Firefox, Google Chrome, Safari
supported = true;
// if some content is selected, the start position of the search
// will be the end position of the selection
found = window.find (str);
} else {
if (document.selection && document.selection.createRange) { // Internet Explorer, Opera before version 10.5
var textRange = document.selection.createRange ();
if (textRange.findText) { // Internet Explorer
supported = true;
// if some content is selected, the start position of the search
// will be the position after the start position of the selection
if (textRange.text.length > 0) {
textRange.collapse (true);
textRange.move ("character", 1);
}
found = textRange.findText (str);
if (found) {
textRange.select ();
}
}
}
}
if (supported) {
if (!found) {
alert ("The following text was not found:\n" + str);
}
}
else {
alert ("Your browser does not support this example!");
}
}
This is the simplest idea.
Frontend
index.html
$('input').keydown(function(e) {
var str = $(this).val();
alert(str);
$.get("/search.php?query=" + str, function(data) {
$('.result').html(data);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>File search and download</h3>
<input name="filename" placeholder="file name" class="kw"/>
<div class="result">
</div>
Backend
search.php
<?php
// You need code search file
// after search $files
$str = '';
foreach($files as file) {
$str .= ''.$file.' <br>'
}
return $str;
?>
readfile.php
<?php
// PHP script to allow the file to be downloaded
$filename = $_GET['file'];
if (file_exists($filename)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment;
filename="'.basename($filename).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($filename);
exit;
}
?>
this really easy. you just need to use event keyup and some code fix
index.php
<input type="text" id="searchbar" placeholder="search file"> <span id="loading" style="display:none;">loading</span>
<div id="result"></div>
<script src="../../vendor/jquery/jquery-3.2.1.min.js"></script>
<script>
$(function(){
$('#searchbar').keyup(function(){//event after user release keyboard
var val = $(this).val();
if(val.length >= 2){//min 2 words to start find
$.ajax({
url: 'search.php',
type: 'POST',
dataType: 'json', //we use json
data: {keyword: val},
beforeSend: function(){
$('#loading').show();
},
success: function(d){
if(d.ok==1){
$('#result').html(d.list);
}else{
alert(d.msg);
}
$('#loading').hide();
},
error: function(d){
alert('error');
$('#loading').hide();
}
});
}
})
});
</script>
search.php
<?php
$path = 'C:/xampp/htdocs/';
$keyword = isset($_POST['keyword']) ? $_POST['keyword'] : '';
$scan = scandir($path);
$result = array('ok'=>0); //prepare output cz we will use json instead text/html
if($scan !== false){
$result['ok']=1;
$list = array();
foreach($scan as $file){
if(is_file($path.$file)){ //only file
if(preg_match('/'.$keyword.'/', $file)) //is file containts keyword?
$list[] = '<div>'.$file.'</div>';
}
}
$result['list'] = count($list) == 0 ? 'no file match': $list;
}else
$result['msg'] = "failed open dir";
echo json_encode($result);
readfile.php
<?php
// PHP script to allow the file to be downloaded
$filename = $_GET['file'];
$path = 'C:/xampp/htdocs/';
$fullPath = $path.$filename; //you need this
if (file_exists($fullPath)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($filename).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($fullPath));
readfile($fullPath);
exit;
}
?>
There are many ways to do that.
I would suggest that:
Make your PHP answer a JSON with the files that match a given criteria. So you will ask to the PHP, passing in POST data ou QUERY string the "text" that is being search. It will give you only the files that matches.
In you html file (could be another PHP as well), you will call ajax (you can use jQuery) to the page above everytime user changes the search text. It's good thing to "throttle" (see lodash/underscore library) (wait some time waiting for more key presses).
After receiving the JSON with the files that matches, build dynamically you table (or another way you want).
search.php:
<?php
header('Content-Type: application/json');
$path = '/var/www/html/'; //get list of files
$files = scandir($path);
$search = $_GET['search'];
$links = array();
foreach ($files as $file) {
if($file != '.' && $file != '..' && strpos(strtolower($file), strtolower($search)) !== false) {
array_push($links, array(
"name" => $file,
"url" => "readfile.php?file=" . urlencode($file)
));
}
}
echo json_encode($data);
?>
index.php / index.html
<html>
<head>
<script src="http://code.jquery.com/jquery-2.2.4.min.js">
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js">
</head>
<body>
<input id="searchbox" type="text" placeholder="search for files" />
<div id="results">
</div>
<script>
$(function () {
var searchbox = $("#searchbox");
var results = $("#results");
var doSearch = _.throttle(function () {
var searchtext = searchbox.val();
$.ajax({
type: 'get',
url: 'search.php',
dataType: "json",
data: {
search: searchtext
}
}).done(function (response) {
results.html(response.reduce(function (html, item) {
return html + '<div>' + item.name + '</div>';
}, ''));
});
}, 200);
searchbox.on('keydown', doSearch);
});
</script>
</body>
</html>
I want to send data from php to php and in same time I also want to send data from js to php. I have one index.php which contains php and js part. In enrolled.php I want to collect my data. SQL injection or other security problems are not important. I do not get any error but it does not save to database.
Small part of index.php
<!DOCTYPE html>
<html lang="en">
<head>
//smt....Not important
</head>
<body>
//smt....Not important
<div id="dom-target" style="display: none;">
<?php
include_once "connection.php";
session_start();
$username = $_SESSION['username'];//coming from previous page.
echo htmlspecialchars($username); //for sending variable from php to js.
?>
</div>
<script type = "text/javascript">
$('#addmore').click(function(){
var subjectone = $('#selectedsubjectone :selected').val();
var courseone = $('#courseListone').val();
var gradeone = $('#selectedGradeOne :selected').val();
var div = document.getElementById("dom-target");
var username = div.textContent;//these lines help to gett data from php
document.getElementById("usernamee").innerHTML = username;//for checking
$.ajax({
type: "POST",
url: "addenrolled.php",
data: {
// Send the username (js, not php)
username: username,
subject: subjectone,
course: courseone,
grade: gradeone
}, success: function(data) {
alert("sucess");
}
});
});
</script>
</body>
</html>
enrolled.php
<?php
include_once "connection.php";
$nick = $_POST['username'];
$subject=$_POST['subject'];
$course=$_POST['course'];
$grade=$_POST['grade'];
echo "$nick -- $subject -- $course -- $grade"; //for checking
$prep = $con->prepare("INSERT INTO enrolledtable ('nickname', 'subject', 'course', 'grade') VALUES(?,?,?,?)");
$prep->bind_param("ssss", $nick, $subject, $course, $grade);
$send = $prep->execute();
if ($send == TRUE) {
echo "Courses added successfully";
header('Location: index.php');
exit();
} else {
echo "Error: " . $con->error;
header('Location: index.php');
exit();
}
?>
Change your jQuery to this
<script>
$(document).ready(function(){
$('#addmore').click(function(){
var subjectone = $('#selectedsubjectone :selected').val();
var courseone = $('#courseListone').val();
var gradeone = $('#selectedGradeOne :selected').val();
$.post('enrolled.php', {subjectone: subjectone, courseone: courseone, gradeone: gradeone, addmore: "yes"}, function(response){
console.log(response);
})
});
});
</script>
Then in your PHP modify the prepare statement to the following
$prep = $conn->prepare("INSERT INTO enrolledtable (`nickname`, `subject`, `course`, `grade`) VALUES(?,?,?,?)");
$prep->bind_param("ssss", $nick, $subject, $course, $grade);
$send = $prep->execute();
enrolled.php
<?php
session_start();
include_once "connection.php";
if (isset($_POST['addmore'])) {
$nick = $_SESSION['username'];
$subject=$_POST['subjectone'];
$course=$_POST['courseone'];
$grade=$_POST['gradeone'];
// //echo "$nick -- $subject -- $course -- $grade"; //for checking
$prep = $conn->prepare("INSERT INTO enrolledtable (`nickname`, `subject`, `course`, `grade`) VALUES(?,?,?,?)");
$prep->bind_param("ssss", $nick, $subject, $course, $grade);
$send = $prep->execute();
if ($send == TRUE) {
echo "Courses added successfully";
// header('Location: index.php');
exit();
} else {
echo "Error: " . $con->error;
//header('Location: index.php');
exit();
}
}
?>
I've looked around on the internet for answers, but I couldn't find any specific to my situation. As mentioned in the title, i'm trying to retrieve and then display a certain value from mysql database.
Disregarding the security measures which I will add later on, I've managed to retrieve the data, but when I send it back to the javascript and alert it, this value is returned: {"acc_points":"5"}. I would like it it to be just "5", is there any way that I can do this? Thanks!
Here are the codes:
js file
$(document).ready(function() {
$("#viewpoints").click(function() {
{
$.ajax({
type: "GET",
url: "http://127.0.0.1/MP/apppoints.php?callback=?",
dataType: 'JSONP',
async: false,
jsonp : "callback",
jsonpCallback: "jsonpcallback",
success: function jsonpcallback(response)
{
alert(JSON.stringify(response));
}
})
}
});
});
php file
<?php
header('Content-Type: application/json');
require 'dbcon.php';
session_start();
$acc_id = $_SESSION["acc_id"];
$sql = "SELECT acc_points FROM points WHERE acc_id = '$acc_id'";
$result = mysqli_query($con, $sql);
$acc_points = mysqli_fetch_assoc($result);
if($acc_points != null)
{
$response = $acc_points;
echo $_GET['callback'] . '(' . json_encode($response) . ')';
}
else
{
$response = "Failed. Please try again.";
echo $_GET['callback'] . '(' . json_encode($response) . ')';
}
//connection closed
mysqli_close ($con);
?>