I'm going to export all of my data in mySQL using PHPExcel with CSV Format. Here is my code:
function exportHartatoCSV() {
$memberid = $this->input->post('memberid');
$tahun = $this->input->post('tahunpajak');
$this->db->where('taxYear', $tahun);
$this->db->where('memberID', $memberid);
$query = $this->db->get('list_harta');
$this->load->library("excel");
$objPHPExcel = new PHPExcel();
$objPHPExcel->setActiveSheetIndex(0)
->setCellValue('A1', 'Tahun Pajak')
->setCellValue('B1', 'Pembetulan')
->setCellValue('C1', 'Kode Harta')
->setCellValue('D1', 'Jenis Harta')
->setCellValue('E1', 'Tahun Perolehan')
->setCellValue('F1', 'Harga Perolehan')
->setCellValue('G1', 'Keterangan');
$row = 2;
$workbookName = $this->MemberModel->getNPWP($memberid);
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="'.$workbookName.'.csv"');
header('Cache-Control: max-age=0');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'CSV');
$objWriter->setDelimiter("\t");
$objWriter->setEnclosure('');
$total = 0;
foreach ($query->result() as $key) {
$objPHPExcel->getActiveSheet()->setCellValue('A'.$row, $key->taxYear);
$objPHPExcel->getActiveSheet()->setCellValue('B'.$row, $key->pembetulan);
$objPHPExcel->getActiveSheet()->setCellValue('C'.$row, $key->hartaID);
$objPHPExcel->getActiveSheet()->setCellValue('D'.$row, $key->hartaName);
$objPHPExcel->getActiveSheet()->setCellValue('E'.$row, $key->hartaYear);
$objPHPExcel->getActiveSheet()->setCellValue('F'.$row, $key->hartaPrice);
$objPHPExcel->getActiveSheet()->setCellValue('G'.$row, $key->hartaDesc);
$total += $key->hartaPrice;
$row++;
}
$objPHPExcel->getActiveSheet()->setCellValue('E'.$row, "Total Harta:");
$objPHPExcel->getActiveSheet()->setCellValue('F'.$row, $total);
$objWriter->save('php://output');
}
I want to change the delimiter from , to tab (like writing data to the next column. But it doesn't work. The strings are stick to each other. The output is like this:
Output
But I want the output is like this:
Expected Output
What I really want is a normal-looking excel table, but with .csv format.
So you need tab-delimited text (csv) file or you just want "normal"-looking excel table?
You must remember that there is a system list delimiter that is used in excel by default. In windows you can set that delimiter in your Region and Language, in Additional settings. It's called as List separator there. In some countries default value is ";", in others ",".
If you don't want to change your default delimiter you have an option to choose delimiter in Excel when you open file.
Update
You can use both options, but it looks like it's easier to set the delimiter in PHPExcel export settings to that delimiter that is set by default in your client's OS, than explain them to set custom delimiter in excel when opening file.
$objWriter->setDelimiter(";");
or
$objWriter->setDelimiter(",");
Update 2
If you have clients from different countries and/or they use different operating systems (mac/linux, windows), so they may have different system separators, then you'll need to save 2 versions of each file (with both , and ; delimiters). Or you'll need to explain them how to work with it.
I'm putting this system setting screenshots just for example:
Mac OS
Windows
As #teeyo mentioned, you might need to make sure you import it using the delimiter in Excel (or other spreadsheet editor). It might already be correct in the data generated by CI:
To verify the data is correct in the file itself, you can open it in eg. Notepad++ and use the Show All Characters feature:
Related
I want to arrange the data as in a text file but its format has been changed when I tried to get the file from a directory and displayed it in an app the problem for me is it has no reference point at the line ending so I don't know how can I explode it Here is the file format:
This is how data should look
and this is how I am getting data:
This is how m getting the data now
one more thing from these lines I want to pick some data to be stored how can I pick data without reference points?
I mean as you see here:
PIDF***HEMP ZONE ULTRA THIN ROLLING PAPERS 1.25" 25CT~
we have * and ~ to explode and get the data in array format but how can we pick data when the data is like that:
B84921501625VSSE ALTO MENT 463405005397BX00090500360078000
"as I want to pick the name "ALTO MENT" 4, "63405005397
how can I pick that data?
Here is what I did till now:
public function read_confirmation(){
$cpath = public_path('confirmations\pending');
$c_allfiles = scandir($cpath);
$c_allfiles = array_diff(scandir($cpath), array('.', '..'));
foreach ($c_allfiles as $fname) {
$file= File::get(public_path('confirmations\pending/'.$fname));
return $file;}
}
I am trying to generate an Excel file with CodeIgniter and the PhpSpreadsheet library from a view. The reports that I need to make are not a list but much more complex and I can generate them more quickly with a view and sending parameters. This is my code:
$data = $this->model->bringdata();
$view = $this->load->view("data_view", $ data);
$spreadsheet = new Spreadsheet();
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Html($spreadsheet);
$writer-> save($view);
And the following error is shown
Severity: Warning
Message: fopen (): Filename can not be empty
Filename: Writer / Html.php
Line Number: 160
In the PhpSpreadsheet documentation it shows that an html page must be explicitly sent:
$writer->save("05featuredemo.htm");
Is there any way to do what I need?
Thanks for the help
It's a simple solution, you need to pass true to the third argument of load->view in order for it to return a string rather than sending it to the browser.
$view = $this->load->view("data_view", $ data, true);
Added after comment
I made the mistake of not looking into how the Html writer works.
The HTML writer writes a spreadsheet as an html file. It does not create a spreadsheet. As I understand it (and I might be mistaken) you can use \PhpOffice\PhpSpreadsheet\Reader\Html to read an html file into a spreadsheet.
In your case I think you will have to save the string returned from $this->load->view() to a temporary file. CodeIgniter's file_helper might be useful here.
You then read the temporary file to create a spreadsheet. After that you can use $writer to save the spreadsheet somewhere as any of the file types the PhpSpreadsheet supports.
$view = $this->load->view("data_view", $data, true);
$this->load->helper("file");
$fileName = "temp_file_name.html";
$path = "full/path/to/some_writable_folder/";
$path_file = $path . $fileName;
if (write_file($path_file, $view))
{
//create spreadsheet the temp html
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Html();
$spreadsheet = $reader->load($path_file);
//write out to html file
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Html($spreadsheet);
$writer->save($path."05featuredemo.htm");
//delete the temporary file
unlink($path_file);
}
else
{
//handle the failure to write the temp file
}
I haven't tested this and I'm not sure you really want to save to an html file, but I think the above is close to the answer.
Second addition
If you want to save .xlsx files you need an Xlsx writer. Use the following instead of what's shown above.
//write out to excel file
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save($ path. "doc.xlsx");
I confess that I have never used, or considered using the html reader so I'm not sure you'll get what you want. I honestly think that creating an html table so you can import it into excel is probably doing it the hard way.
In Excel you can open a CSV file and click on "Text to Columns" (under "Data" tab) to have a column delimited file.
Is there any way to simulate this using X++? A class that would open the CSV file and apply the exact same Excel "Text to Columns" action?
You can use the InFieldDelimiter method of the CommaIo class to use the correct delimiters.
Or use str2con to split a string.
You can even read an Excel file using ExcelIo.
Update:
As your file is not CSV use str2con:
for (con = commaIo.read(); commaIo.status() == IO_Status::Ok; con = commaIo.read())
{
lineNum++;
if (lineNum > 1 && conlen(con))
con = str2con(conPeek(con,1));
info(str2con(con));
}
This may not remove quotes and trailing spaces, do this for interesting string fields:
purchId = strRtrim(strRem(conPeek(con,3),'"'));
I'm having some trouble with reading out the IPTC data of some images, the reason why I want to do this, is because my client has all the keywords already in the IPTC data and doesn't want to re-enter them on the site.
So I created this simple script to read them out:
$size = getimagesize($image, $info);
if(isset($info['APP13'])) {
$iptc = iptcparse($info['APP13']);
print '<pre>';
var_dump($iptc['2#025']);
print '</pre>';
}
This works perfectly in most cases, but it's having trouble with some images.
Notice: Undefined index: 2#025
While I can clearly see the keywords in photoshop.
Are there any decent small libraries that could read the keywords in every image? Or am I doing something wrong here?
I've seen a lot of weird IPTC problems. Could be that you have 2 APP13 segments. I noticed that, for some reasons, some JPEGs have multiple IPTC blocks. It's possibly the problem with using several photo-editing programs or some manual file manipulation.
Could be that PHP is trying to read the empty APP13 or even embedded "thumbnail metadata".
Could be also problem with segments lenght - APP13 or 8BIM have lenght marker bytes that might have wrong values.
Try HEX editor and check the file "manually".
I have found that IPTC is almost always embedded as xml using the XMP format, and is often not in the APP13 slot. You can sometimes get the IPTC info by using iptcparse($info['APP1']), but the most reliable way to get it without a third party library is to simply search through the image file from the relevant xml string (I got this from another answer, but I haven't been able to find it, otherwise I would link!):
The xml for the keywords always has the form "<dc:subject>...<rdf:Seq><rdf:li>Keyword 1</rdf:li><rdf:li>Keyword 2</rdf:li>...<rdf:li>Keyword N</rdf:li></rdf:Seq>...</dc:subject>"
So you can just get the file as a string using file_get_contents(get_attached_file($attachment_id)), use strpos() to find each opening (<rdf:li>) and closing (</rdf:li>) XML tag, and grab the keyword between them using substr().
The following snippet works for all jpegs I have tested it on. It will fill the array $keys with IPTC tags taken from an image on wordpress with id $attachment_id:
$content = file_get_contents(get_attached_file($attachment_id));
// Look for xmp data: xml tag "dc:subject" is where keywords are stored
$xmp_data_start = strpos($content, '<dc:subject>') + 12;
// Only proceed if able to find dc:subject tag
if ($xmp_data_start != FALSE) {
$xmp_data_end = strpos($content, '</dc:subject>');
$xmp_data_length = $xmp_data_end - $xmp_data_start;
$xmp_data = substr($content, $xmp_data_start, $xmp_data_length);
// Look for tag "rdf:Seq" where individual keywords are listed
$key_data_start = strpos($xmp_data, '<rdf:Seq>') + 9;
// Only proceed if able to find rdf:Seq tag
if ($key_data_start != FALSE) {
$key_data_end = strpos($xmp_data, '</rdf:Seq>');
$key_data_length = $key_data_end - $key_data_start;
$key_data = substr($xmp_data, $key_data_start, $key_data_length);
// $ctr will track position of each <rdf:li> tag, starting with first
$ctr = strpos($key_data, '<rdf:li>');
// Initialize empty array to store keywords
$keys = Array();
// While loop stores each keyword and searches for next xml keyword tag
while($ctr != FALSE && $ctr < $key_data_length) {
// Skip past the tag to get the keyword itself
$key_begin = $ctr + 8;
// Keyword ends where closing tag begins
$key_end = strpos($key_data, '</rdf:li>', $key_begin);
// Make sure keyword has a closing tag
if ($key_end == FALSE) break;
// Make sure keyword is not too long (not sure what WP can handle)
$key_length = $key_end - $key_begin;
$key_length = (100 < $key_length ? 100 : $key_length);
// Add keyword to keyword array
array_push($keys, substr($key_data, $key_begin, $key_length));
// Find next keyword open tag
$ctr = strpos($key_data, '<rdf:li>', $key_end);
}
}
}
I have this implemented in a plugin to put IPTC keywords into WP's "Description" field, which you can find here.
ExifTool is very robust if you can shell out to that (from PHP it looks like?)
I use smarty to allow different languages on my site, which works OK so far. I store the texts in config files in different sections.
But then there are sentences like this:
"You have 6 new mails!", which would be in german "Sie haben 6 neue Mails!"
Now there's text before the number and behind the number, which is loaded from the database. And I would like to put it into the config file and just load the number on its own.
so I have this in my "text.conf"
[en]
mail_count = "You have $NUMBER new mails!"
[de]
mail_count = "Sie haben $NUMBER neue Mails!"
and this in my "show_text.php"
$smarty->assign('NUMBER', 6);
Is something like this possible? Maybe with Smarty 3.0?
Thanks in advance,
BH
You can use the sprintf sintax. This example comes from a pager-like thing:
results = "Results %s to %s of %s total"
{#results#|sprintf:$start:$end:$total}
I just tried this and it works, but it's rather ugly...
create a file "number.tpl" which contains
{$NUMBER}
in your conf file go like this
mail_count = "You have {include
file='number.tpl'} new mails!"
I guess it's because the smarty variables only work in tpl files.
When reading the config file, you need to open it using
$cfg = $smarty->fetch('path/to/file');
After that you have the whole files content ind the $cfg variable, with {$NUMBER} replaced.
I don't have Smarty to test this right now but it should work if you properly declare the variable in your config entry, like:
ail_count = "You have {$NUMBER} new mails!"