I am exporting content from an MySQL database to a Word Template (RTF) via PHP.
There is a section, "Appendix B", which should display all the Acronyms found for a record. The minimum records to appear for this section is 90 (i.e. these are standard acronyms (tblAcronyms) that each record will have); however the maximum records are unknown since users can add to this listing (tblAppendixB).
The Word (i.e. RTF) document should display all the records found, however, it is only displaying the first record.
This is what I have thus far:
<?php
....
#Retrieve Appendix B records
$qry_get_AppB = "SELECT vAcronym, vAcronymDesc FROM tblAcronyms
UNION SELECT vAcronym, vAcronymDesc FROM tblAppendixB
WHERE fkID = ". $i_fk_id . " ORDER BY vAcronym ASC";
$qry_appb_result = mysql_query($qry_get_AppB);
$qryAppBno_rows = mysql_num_rows($qry_appb_result);
//Generate the headers to help a browser choose the correct location
header('Content-Type: application/msword');
header('Content-Disposition: inline; filename="'.$vProgramName.'_rec.rtf");
//Open the template file
$tfilename = 'Appb_Template.rtf';
$fp = fopen($tfilename, 'r');
//Read the template into a variable
$toutput = fread($fp, filesize($tfilename));
fclose($fp);
//Replace the place holders in the template with data
if($qryAppBno_rows > 0)
{
while($rowAppB = mysql_fetch_array($qry_appb_result))
{
$vAppB = $rowAppB['vAcronym'] . '-' . $rowAppB['vAcronymDesc'] . "\r\n";
$toutput = str_replace('<<vAppB>>', $vAppB, $toutput);
}
}
//Send the generated document to the browser
echo $toutput;
?>
I have searched this forum and others but have yet to find a solution.
Any assistance is greatly appreciated.
Okay, I'm not quite sure what your template looks like, but I guess, you only have 1 place holder named <<vAppB>>. In your 1st iteration (if there is any data available) you replace that placeholder with your 1st data entry. In this fact only one placeholder is shown.
May rewrite your code to something similar to this
... //do your stuff
$newLine = "\r\n";
$appendix = "";
while($rowAppB = mysql_fetch_array($qry_appb_result)) {
$appendix .= $rowAppB['vAcronym'] . '-' . $rowAppB['vAcronymDesc'] . $newLine;
}
$toutput = str_replace('<<vAppB>>', $appendix, $toutput);
...//do some other stuff
Just simple prototyping, so you may have to do some additional work.
The trick is to collect all entries you got and than replace it with your placeholder :)
I resolved the problem; I had to use "\par" instead of "\r\n" for MS Word (RTF) to recognize it as a paragraph mark. Here is the modified code that now works:
<?php
....
$t_newline = "\par";
#Retrieve Appendix B records
$qry_get_AppB = "SELECT vAcronym, vAcronymDesc FROM tblAcronyms
UNION SELECT vAcronym, vAcronymDesc FROM tblAppendixB
WHERE fkID = ". $i_fk_id . " ORDER BY vAcronym ASC";
$qry_appb_result = mysql_query($qry_get_AppB);
$qryAppBno_rows = mysql_num_rows($qry_appb_result);
//Generate the headers to help a browser choose the correct location
header('Content-Type: application/msword');
header('Content-Disposition: inline; filename="'.$vProgramName.'_rec.rtf");
//Open the template file
$tfilename = 'Appb_Template.rtf';
$fp = fopen($tfilename, 'r');
//Read the template into a variable
$toutput = fread($fp, filesize($tfilename));
fclose($fp);
//Replace the place holders in the template with data
if($qryAppBno_rows > 0)
{
while($rowAppB = mysql_fetch_array($qry_appb_result))
{
$vAppendixB[] = $rowAppB['vAcronym'] . '-' . $rowAppB['vAcronymDesc'] . $t_newline;
$vAppB = implode(" ", $vAppendixB);
}
}
$toutput = str_replace('<<vAppB>>', $vAppB, $toutput);
//Send the generated document to the browser
echo $toutput;
?>
Hopefully this will help someone else. :-)
Related
I'm trying to import and fetch data from CSV file and store it in my database
my database table schema is like this
users ( ID , Fname , Lname, user_type , major , Bday , Email,password , image , status )
csv ( 111 , Leo , pichon, , business, , leo#yzu.cn )
and this is my csv file schema , columns only matching the required filed of my database schema its somthing like this :
'' the empty filed either have default value or null ''
after importing i get the following notice for almost each row of my data file :
Undefined offset: 1 in php csv
here's my php function :
if ($_GET['action'] = 'UsersCvs') {
if (isset($_FILES['users_cvs']['name'])) {
$file = $_FILES['users_cvs']['tmp_name'];
if ($_FILES["users_cvs"]["size"] > 0) {
$handle = fopen($file, "r");
$c = 0;
while (($files = fgetcsv($handle, 2000, ",")) !== false) {
// $id = mysqli_real_escape_string($link , $files[0]);
// $fname = $files[1];
// $lname = $files[2];
// $user_type = $files[3];
// $major = $files[4];
// $email = $files[6];
// $gender = mysqli_real_escape_string($link, $filesop[6]);
//$sql = "INSERT INTO users(ID , Fname,Lname , user_type , major , Email) values ('" . $id . "','" . $fname . "' ,'" . $lname . "' ,'" .$user_type. "','" . $major . "','" . $email . "')";
// mysqli_query($link, $sql);
$num = count($files);
echo "<p> $num fields in row $c: <br /></p>\n";
$c++;
for ($i = 0; $i < $num; $i++) {
echo $files[$i] . "<br />\n";
}
}
fclose($file);
// if ($sql) {
// echo 1 ;
// } else {
// echo mysqli_error($link); ;
// }
} else {
}
}else{
echo 'no file found';
}
}
what seems strange to my and after inspection my data gets encoded to unreadable string
somthing like this
<p> 3 fields in line 2: <br /></p>
�Ѷѩ\h�1�������
��drKK(G~�S⼥���Nw|x���
�s�k�Ŗ�X���J�fb�fWш�eʬ�y�`hc�g�
1 fields in line 3:
���y��Q�b~���^�)�Ϸ�������LD?��r�:��DN��(����C��*T�?��C��!�&�e���!_�8��+[�|��PK�N�#}�":[docProps/core.xml��QK�0���C�{��cm*{r 8Q|��lҐD��{�v����c�9���^R������:��� Ah���%zٮ���gZ���P�8��no
2 fields in line 4:
I've really tried my best and did online research but i couldn't find any matching reference
i would highly appreciate help thanks in advance
The file you are trying to process is not a CSV file, but an Excel workbook (a ".xlsx" file).
There are two clues here:
First, the data you're seeing clearly isn't human-readable text. A CSV file is just a text file formatted to a particular convention, whereas this looks very much like binary data intended only for machine use.
The very short snippet you posted happened to include the string "docProps/core.xml". If you search for that online, you'll get lots of references to the "Office Open XML" format used by modern versions of Microsoft Office. The files are structured as a zip file containing multiple XML files, and that's the name of one of the internal files in the zip.
The first thing you should do is add some validation to your code. Input from the user always needs validating, and in this case a check for the expected number of fields, or a mandatory header row, would have given you an error straight away.
The second thing you should do is either a) tell the user to export the spreadsheet as a CSV file, or b) re-write the code using a library that can read Excel files, such as PhpSpreadsheet.
I need get a list of all file url in one of my database field.
mysql database, article table
`id` | `subject` | `content`
the value of content is html text with one or more file url, for example:
<p>this is the answer for ..., you can refer to below screenshot:</p>
<img src="http://the_url_of_image_here/imagename.jpg/>
<p>or refer to below document</p>
<a href="http://the_url_of_doc_here/guide.ppt>guide</a>
<a href="http://the_url_of_doc_here/sample.dox>sample</a>
there are 2 types of files
image,with extension jpg,jpeg,png,bmp,gif
document, with extension doc,docx,ppt,pptx,xls,xlsx,pdf,xps
I did a lot goolge, look like it's hard to do it only with mysql, php would make it easy, I write my codes but it can not work.
Thanks cars10, I solved it.
function export_articles_link()
{
global $date_from, $date_to;
$filename = "kb_articles_link_".$date_from."_".$date_to.".xlsx";
header('Content-disposition: attachment; filename="'.XLSXWriter::sanitize_filename($filename).'"');
header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate');
header('Pragma: public');
$query = 'SELECT `content` FROM `kb_articles` WHERE ((DATE(`dt`) BETWEEN \'' . $date_from . '\' AND \'' . $date_to . '\') AND (`content` LIKE \'%<img src=%\' or `content` LIKE \'%<a href="http:%\')) order by id asc';
$result = mysql_query($query);
$writer = new XLSXWriter();
$img_list = array();
while ($row=mysql_fetch_array($result))
{
$text = $row['content'];
preg_match_all('!http://.+\.(?:jpe?g|png|gif|ppt?|xls?|doc?|pdf|xdw)!Ui', $text, $matches);
$img_list = $matches[0];
foreach ($img_list as $url)
{
$writer->writeSheetRow('Sheet1', array($url)); // if more than one url it will be put on first column
}
};
$writer->writeToStdOut();
exit(0);
}
share with others who need a work sample,hope it save your time.
You should change your central loop to something like
$image_list=array(); // prepare an empty array for collection
while ($row=mysql_fetch_array($result))
{
$text = $row['content'];
preg_match_all('!http://.+?\.(?:jpe?g|png|gif|pptx?|xlsx?|docx?|pdf|xdw)!i', $s, $matches);
$img_list=array_merge($image_list,$matches[0]); // append to array
}
$writer->writeSheetRow('Sheet1', $image_list);
Since you did not clearly specify what was wrong I just guessed and went ahead: The regular expression is slightly different from your original and also the way I structured the loop (yes, only one is needed). preg_match_all only needs to be called only once for each $text and then you merge the results from $matches[0] into your $img_list-array.
I also removed your U-modifier, which was inverting the "greediness" of the whole regexp. Instead I added a ? after the + to make this one quantifier "non-greedy".
I prepared a little minimalistic demo here: http://rextester.com/JDVMS87065
I am trying to download table data into a CSV format. The data in one of the fields contains ",".
Eg: Doe, John
When I download the csv file, the data after comma is shifted to next column. But I want the entire data i.e including comma in same column.
The Code I used as follows:
<?php
include('dbconfig.php');
//header to give the order to the browser
header('Content-Type: text/csv');
header('Content-Disposition: attachment;filename=download.csv');
//select table to export the data
$sql ="SELECT * FROM tablename";
$select_table=mysqli_query($db, $sql);
$rows = mysqli_fetch_assoc($select_table);
if ($rows)
{
getcsv(array_keys($rows));
}
while($rows)
{
getcsv($rows);
$rows = mysqli_fetch_assoc($select_table);
}
// get total number of fields present in the database
function getcsv($no_of_field_names)
{
$separate = '';
// do the action for all field names as field name
foreach ($no_of_field_names as $field_name)
{
if (preg_match('/\\r|\\n|,|"/', $field_name))
{
$field_name = '' . str_replace('<em>', '', $field_name) . '';
}
echo $separate . $field_name;
//sepearte with the comma
$separate = ',';
}
//make new row and line
echo "\r\n";
}
?>
Can someone help me get through this issue.
Thanks
Make sure you escape the ,. Typically values that contain sensitive characters (such as , and \n) are surrounded in ".
So your output can be:
"Doe, John",52,New York
You can either write your own escape function or use PHPs fputcsv. It writes to a file handler that's a bit inconvenient but you can make it stdout.
$handle = fopen("php://stdout");
fputcsv($handle, array("Doe, John", 52, "New York"));
I have a mysql statement and I would like to store the data it fetches in a csv file in tab format. I have used the following statment but it is not creating and storing the results when I run my file and no error files.
$mytry = "SELECT * FROM table WHERE `assigned` = '$id'
INTO OUTFILE '/inactive/orders.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '\"'
LINES TERMINATED BY '\n'";
mysql_query($mytry);
Or there a way I can write to file in a directory without prompting the user to download, this works but it prompts
$sQuery="SELECT * FROM table WHERE `assigned` = '$id'";
$rResult = mysql_query( $sQuery) or die();
$count = mysql_num_fields($rResult);
$html = '<table border="1"><thead><tr>%s</tr><thead><tbody>%s</tbody></table>';
$thead = '';
$tbody = '';
$line = '<tr>%s</tr>';
for ($i = 0; $i < $count; $i++){
$thead .= sprintf('<th>%s</th>',mysql_field_name($rResult, $i));
}
while(false !== ($row = mysql_fetch_row($rResult))){
$trow = '';
foreach($row as $value){
$trow .= sprintf('<td>%s</td>', $value);
}
$tbody .= sprintf($line, $trow);
}
header("Content-type: application/vnd.ms-excel; name='excel'");
header("Content-Disposition: filename=exportfile.xls");
header("Pragma: no-cache");
header("Expires: 0");
print sprintf($html, $thead, $tbody);
exit;
You might want to look into the following PHP function: http://php.net/manual/en/function.fputcsv.php
Fetch the data using your query and then save it to a variable. Then, use fputcsv to store the data to a file.
Also, I would discourage the usage of mysql_query, since it has now become deprecated (as well as the rest of mysql_* family). Furthermore, your code is vulnerable to SQL injection attacks. Read up on using PDO for database interaction.
Some more recommended reading to put you on the right track: http://www.phptherightway.com/#databases
EDIT: From what you have shown in your code sample, you simply output an HTML page to the browser, which gets downloaded right away because of the Content-Disposition header you set.
Everything works perfectly but I've encountered a problem when I'm exporting data to a CSV file. I tried searching for similar problems but I didn't quite find any that could be relevant to my problem.
This code here is supposed to export the whole database table from mySQL database. It does it perfectly but the thing is, it puts all the data in the first column - in different cells.
The cell placement is alright but it's supposed to spread the data over several columns (13 in my case).
Here's the screenshot to explain what's happening:
Code:
<?php
header("Content-type: application/vnd.ms-excel");
header("Content-disposition: filename=export.csv");
#$query=mysql_query("set names 'utf8'");
#mb_http_output('UTF-8');
#mb_http_input('UTF-8');
#mb_language('uni');
#mb_regex_encoding('UTF-8');
#ob_start('mb_output_handler');
#header('Content-type: text/html; charset=utf-8');
$conn = mysql_connect('localhost', 'root', 'asdasd') or die(mysql_error());
mysql_select_db('nooruse', $conn) or die(mysql_error($conn));
$query = sprintf('SELECT osakond as Osakond, soetusaasta as Soetusaasta, it_number as IT_Number, tooteruhm as Tooteruhm, mudeli_nimetus as Mudeli_nimetus, sn as SN, riigivara_nr as Riigivara_nr, inventaari_nr as Inventari_nr, maja as Maja, ruum as Ruum, vastutaja as Vastutaja, markus as Markus,kasutajanimi as Kasutajanimi FROM norse5_proov');
$result = mysql_query($query, $conn) or die(mysql_error($conn));
$row = mysql_fetch_assoc($result);
if ($row) {
echocsv(array_keys($row));
}
while ($row) {
echocsv($row);
$row = mysql_fetch_assoc($result);
}
function echocsv($fields)
{
$separator = '';
foreach ($fields as $field) {
if (preg_match('/\\r|\\n|,|"/', $field)) {
$field = '"' . str_replace('"', '""', $field) . '"';
}
echo $separator . $field;
$separator = ',';
}
echo "\r\n";
}
Thanks in advance.
The problem is you are assuming that Excel knows that a semicolon is the separator.
For some machines this might work, others not.
It was suggested this has to do with regional setting in the control panel under List Separator.
I found a suggestion to add the following as the first line of the CSV to tell excel what separator to use:
sep=;
Haven't tried this, but it seems legit.
Here is a link to a better description (see the 3rd comment down for the way to set the separator in the CSV file to avoid client computer changes):
Trouble with Opening CSV Files with Excel? The Comma and Semicolon Issue in Excel due to Regional Settings for Europe