File downloaded via Podio Export API is not readable through code - php

Use-case:
Export data from different apps using batch EXPORT APIs to merge into a master excel file and use it for reporting purpose...
Implementation Details
I'm using Podio export API to get data from an application. Application name is Kall8-number-text (as an example).. here is the code snippet
Code Snippet
$batch_id = PodioItem::export(11804702,"xlsx",array("filters" => array( "kall8-number-text" => "510-592-5916") ));
PodioBatch::get( $batch_id );
$file = PodioFile::get($file_id);
// Download the file. This might take a while...
$file_content = $file->get_raw();
// Store the file on local disk
$path_to_file= "downloads/".$name;
file_put_contents($path_to_file, $file_content);
Problem Description:
I'm trying to read downloaded file using phpexcel library but getting error "You tried to set a sheet active by the out of bounds index: 0. The actual number of sheets is 0"
This error shows that file has NO sheet but it is not true. File has data/sheet and it shows upon opening that file.
One interesting fact, if I open the same excel file (manually by double click) and SAVE without making any change, then same code works fine. In my end to end process, I cannot add a manual step to open file every-time to proceed further...
For your information, I thought this is a PHPExcel bug and contacted Mark Backer (coordinator PHPOffice Suit) and he replied with following remarks which seems true.
"My guess would be non-standard namespacing in the file that's generated, which loading and saving in MS Excel fixes"
File Reading Code
$objReader = new PHPExcel_Reader_Excel2007();
$objReader->setReadDataOnly(true);
$objPHPExcel = $objReader->load('callsheet.xlsx');
$objPHPExcel->setActiveSheetIndex(0);
$dataArray = $objPHPExcel->getActiveSheet()->toArray(null, true,true,true);
var_dump($dataArray);
Error Trace
Fatal error: Uncaught exception 'PHPExcel_Exception' with message 'You tried to set a sheet active by the out of bounds index: 0. The actual number of sheets is 0.' in E:\xampp\htdocs\podioexcel\Classes\PHPExcel.php:688 Stack trace: #0 E:\xampp\htdocs\podioexcel\test.php(18): PHPExcel-
setActiveSheetIndex(0) #1 {main} thrown in E:\xampp\htdocs\podioexcel\Classes\PHPExcel.php on line 688
Can you help me to address this issue? This is holding up my project completely.
File Path: https://drive.google.com/file/d/0B79S561prrEBUDY1NEhXQ1JySWM/view
Original question at Stackoverflow: Error While loading excel sheet Using phpexcel
Ejaz

Related

Reading File With PhpSpreadsheet Sheet Out of Bounds Error

Trying to read from a XLSX file with PhpSpreadsheet however getting below error:
PHP Fatal error: Uncaught PhpOffice\PhpSpreadsheet\Exception: Your requested sheet index: -1 is out of bounds. The actual number of sheets is 0. in C:\php\projects\stock\vendor\phpoffice\phpspreadsheet\src\PhpSpreadsheet\Spreadsheet.php:678
There is definitely a worksheet and my code below to pull a single cell works fine when I remove the table and just have unformatted data.
$spreadsheet = new PhpOffice\PhpSpreadsheet\Spreadsheet();
$inputFileName = "path/to/temp_file_download.xlsx";
$inputFileType = \PhpOffice\PhpSpreadsheet\IOFactory::identify($inputFileName);
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
$spreadsheet = $reader->load($inputFileName);
echo $cellValue = $spreadsheet->getActiveSheet()->getCellByColumnAndRow(2, 2)->getValue();
It seems that saving the file with Excel allows it to work just fine however excel does not complain that it is corrupt etc. I have no control over the actual spreadsheet as generated from an external source.
Just wondering if anyone has had similar issues and have any ideas for working around or what I may be doing wrong?
Tried to use the older PhpExcel also to get this to work however similar issues occur until I save the file again.
Have also tried XLSXReader with similar issues:
PHP Fatal error: Uncaught Exception: File /xl/workbook.xml does not exist in the Excel file in C:\php\projects\stock\vendor\XLSXReader\XLSXReader.php:57
Stack trace:
#0 C:\php\projects\stock\vendor\XLSXReader\XLSXReader.php(70): XLSXReader->getEntryData()
#1 C:\php\projects\stock\vendor\XLSXReader\XLSXReader.php(47): XLSXReader->parse()
#2 C:\php\projects\stock\stock.php(17): XLSXReader->__construct()
#3 {main}
thrown in C:\php\projects\stock\vendor\XLSXReader\XLSXReader.php on line 57
And have seen many issues on web for people having issues reading these files that area created like so however still not sure of a simple workaround.
Adding the workaround mentioned below hack for non standard xlsx seemed to do the trick!
https://github.com/PHPOffice/PHPExcel/issues/1187
Just need to add the class extending the xlsx class to phpspreadsheet then call that class instead and all works!

Error While loading excel sheet Using phpexcel

I am trying to load excel sheet (generated by other application) using phpexcel library, with following code:
$objReader = new PHPExcel_Reader_Excel2007();
$objReader->setReadDataOnly(true);
$objPHPExcel = $objReader->load('callsheet.xlsx');
$objPHPExcel->setActiveSheetIndex(0);
$dataArray = $objPHPExcel->getActiveSheet()->toArray(null, true,true,true);
var_dump($dataArray);
But I got this error.
Fatal error: Uncaught exception 'PHPExcel_Exception' with message 'You tried to set a sheet active by the out of bounds index: 0. The actual number of sheets is 0.' in E:\xampp\htdocs\podioexcel\Classes\PHPExcel.php:688 Stack trace: #0 E:\xampp\htdocs\podioexcel\test.php(18): PHPExcel->setActiveSheetIndex(0) #1 {main} thrown in E:\xampp\htdocs\podioexcel\Classes\PHPExcel.php on line 688
One interesting thing. when I open same excel sheet and just save file without any change. Than this code work fine , but problem is that I,m not going to open file each time before to use it. Can you please help me to fix this issue.

PHPExcel - Clone sheet and keep its original style

I've tried to check every possible similar solution both here and in the PHPExcel official documentation / forums, but I didn't find any solution to my issue.
The problem
I'm trying to clone (or copy, being honest) a sheet to parse it into another file created through phpexcel by keeping the style of the cloned sheet.
The setup is:
sheet.xls <--- File to OPEN & COPY
PHPExcel object <-- File that gets created X times in a for loop, where I need to append Y Sheets according to a set of arrays.
What works
The cloning & appending works beautifully, takes time because of some strange notices related to a phpexcel file:
Notice: Undefined offset: 1 in \serverpath\PHPExcel\Classes\PHPExcel.php on line 729
Notice: Undefined offset: 2 in \serverpath\PHPExcel\Classes\PHPExcel.php on line 729
Notice: Undefined offset: 3 in \serverpath\PHPExcel\Classes\PHPExcel.php on line 729
Notice: Undefined offset: 4 in \serverpath\PHPExcel\Classes\PHPExcel.php on line 729
EDIT ::
Line 729 refers to this:
foreach ($sheet->getCellCollection(false) as $cellID) {
$cell = $sheet->getCell($cellID);
++$countReferencesCellXf[$cell->getXfIndex()]; // line 729
}
Which is about styles as far as I can tell.
<-- There are thousand of these, no idea where they are coming from though, the files are getting generated correctly, they just lose their format as said above.
What doesn't work
The generated files LOSES the original format but keeps the formula, hence every single border (and any style) of the original "template" (sheet.xls) is lost.
The relevant part of the code
I'm only posting the really relevant code here, mostly because it's about a thousand lines of code.
File that will later be saved creation (happens in parent foreach) :
$file = new PHPExcel();
Cloning (happens inside a child foreach after the creation above) :
$sd = $objReader->load("sheet.xls");
$sc = $sd ->getActiveSheet()->copy();
$clonedSheet = clone $sc;
Appending (happens N times inside a child foreach of the cloning above) :
$ficheName = "not relevant tbh and less than 31 characters";
$temporarySheet = clone $clonedSheet;
$temporarySheet->setTitle($ficheName);
$file->addSheet($temporarySheet,0);
$file->setActiveSheetIndex($file->getIndex($temporarySheet));
unset($temporarySheet);
// some actions are done here
Saving (outside of the foreach, happens in the same foreach where the PHPExcel object gets created:
$objWriter = PHPExcel_IOFactory::createWriter($file, 'Excel5');
$objWriter->save($filename);
Restrictions
I have absolutely no restrictions about what kind of excel format I'm supposed to use, I'm using 2003 because I have some machines that only works with excel 2003, but they will soon be upgrading to office 2010, so literally any reader and writer is okay, I'm using 2003 because I've always used it and had no problem so far.
I am forced, though, to clone the XLS sheet inside another file, the only possible trick I can do is clone the sheet inside the same file and save it later by keeping the original one, but if there is any other chance to "export" the style I would really appreciate it.
What I have already checked:
PHPExcel clone .xlsm with macros
http://www.mindfiresolutions.com/Cloning-a-XLS-worksheet-in-PHP--Mindfire-Solutions-933.php
PHPExcel 1.8.0 - Creating many sheets by cloning a template sheet gets slower with each clone
Workaround for copying style with PHPExcel
EDIT ::
I've also tried to:
Open the file and get the sheet instead of cloning the original one - Problem persists.
Tried to use Excel2007 both for reading and writing - Problem persist.
Tried NOT to use ->copy() - Problem persists.
UPDATED phpexcel to 1.8, now the Notice above appears on line 1079, but refers to the same exact piece of code - Problem persists.
Okay, I've figured out a possible workaround.
Because the problem seems to be with:
clone
PHPExcel Worksheet ->copy() prototype
Referencing PHPExcel Worksheet
I've thought about that:
Instead of creating a new PHPExcel object instance, just OPEN the original file.
Append the file with other instances of the same file, by copying the sheet still from the same file.
Remove the LAST sheet when finished.
So, in a nutshell, I've changed this:
$file = new PHPExcel();
To this:
$file = $objReader->load("sheet.xlsx"); // decided to work with excel2007
And this:
$objWriter = PHPExcel_IOFactory::createWriter($file, 'Excel5');
$objWriter->save($filename);
To this:
$sheetCount = $file->getSheetCount();
$file->removeSheetByIndex($sheetCount - 1);
$objWriter = PHPExcel_IOFactory::createWriter($file, 'Excel2007'); // same story, excel 2007 instead of 2003
$objWriter->save($filename);
Now I don't have any error and everything is working as expected, despite I'm sure that there may be another cleverer solution.
If you don't change the format of sheet.xls then try to
A) use .xlsx
B) rename *.xlsx to *.zip
C) unzip sheet.zip, and the files you haved saved
D) copy the .xls/styles.xml from sheet to the saved files
E) repack and rename *.zip to *.xlsx
and your format is back.
You can minimize the problem a bit by not generating in a loop in php but rather run the php in a loop.

How to refresh pivot table in excel using php

I have a file in xls format that I need to refresh (use 'refresh all' button in Excel) once a day and then retrieve the data from the pivot table and inset them into the database (MySQL). The file gets data from an external source (retrieve data from sharepoint 2007).
How is the easiest way to do this?
I'm thinking abaout PHP but do I not quite know how you go about it. From what I read PHPExcel does not support this operations.
When you try to use COM I get an error:
Fatal error: in D:\xampp\htdocs\sp\xls\index.php on line 11
And here is a php code:
<?php
// Start Excel
$excel = new COM("Excel.Application") or die ("Could not load Excel.Application");
// Make Excel visible.
$excel->Application->Visible = 1;
// Open workbook
$Workbook = $excel->Workbooks->Open('D:/xampp/htdocs/sp/xls/emails.xls', 'r+') ;
// Refresh all
$Workbook->RefreshAll();
// Save updated excel file out to disk somewhere
$Workbook->SaveAs('D:/xampp/htdocs/sp/xls/emails.xls');
// Close all instances of excel:
$Workbook->Close(false);
unset($Workbook);
$excel->Workbooks->Close();
$excel->Quit();
unset($excel);
?>
I'm using windows 7 and xampp with php 5.5.6
In php.ini I've added this line:
extension=php_com_dotnet.dll
Alternate: is it possible to run *.iqy file generated by sharepoint in php?
I found a workaround to my problem.
Instead, refresh the data by PHP pointed out in a query that collects data during the re-launch of the sheet. To this I added this VBA script save changes and close file.
At the end of the added task scheduler to run the sheet once per day.
The rest of downloading data from Excel using PHPExcel.

phpdocx generatePDF Unknown image type: ?image=opentbs1

First of all, this is my first question on the site and I just want to thank all of you for helping out newbs like me. I have found so much invaluable information on this site! It has helped me with so much along my programming journey.
So here is my question. I have used OpenTBS (PHP class) to fill a .docx template with dynamic data and to insert an image in the document.
The image is inserted by entering the following command into the alternate text of the image:
[onshow.logo_location;ope=changepic;tagpos=inside;adjust=100%;]
I have a variable that I have set as $logo_location that points to the image that is to be inserted.
This step works perfectly. A docx file is created with the appropriate image in the right location.
When I try to convert this docx file to a PDF using phpdocx I get an error. The code to generate the pdf is the following:
require_once '../bbms/classes/phpdocx/classes/TransformDoc.inc';
require_once '../bbms/classes/phpdocx/classes/CreateDocx.inc';
$docx = new CreateDocx();
$document = new TransformDoc();
$document->setStrFile('199.docx');
$document->generatePDF();
The error I get is the following:
Unable to generate PDF file. exception 'DOMPDF_Exception' with message 'Unknown image type: ?image=opentbs1.' in C:\wamp\www\bbms\classes\phpdocx\pdf\include\image_cache.cls.php:188 Stack trace: #0 C:\wamp\www\bbms\classes\phpdocx\pdf\include\image_frame_decorator.cls.php(88): Image_Cache::resolve_url('?image=opentbs1', NULL, '', '') #1 C:\wamp\www\bbms\classes\phpdocx\pdf\include\frame_factory.cls.php(199): Image_Frame_Decorator->__construct(Object(Frame), Object(DOMPDF)) #2 C:\wamp\www\bbms\classes\phpdocx\pdf\include\dompdf.cls.php(606): Frame_Factory::decorate_frame(Object(Frame), Object(DOMPDF)) #3 C:\wamp\www\bbms\classes\phpdocx\classes\TransformDoc.inc(328): DOMPDF->render() #4 C:\wamp\www\discount_database\test.php(23): TransformDoc->generatePDF() #5 {main}
For some reason, the location for the new image in the docx file is being passed as "?image=opentbs1." to the static function resolve_url() in image_cache.cls.php.
When I tried to convert a normal docx file that wasn't created using OpenTBS, I didn't get this error. I checked what a valid url being sent to resolve_url() would look like and it looks like this:
"files/files_invoice_template.docx/media/word/media/image1.png"
Is there a way to configure openTBS to correctly set an inserted image's url / location?
Thank you!!
I don't use PHPDOCX or make PDFs from my OpenTBS stuff, but it looks like PHPDOCX has hardcoded the relationship name into their image recognition. Just looking at the code on github, it looks like if you change line 239 in phpDocx/classes/TransformDoc.inc.php:
foreach ($domImgs[0] as $dats) {
$datsFiltered = explode('"', $dats);
if (preg_match('/^\?image=rId/', $datsFiltered[1])) { // <--this is line 239
$datFiltered = explode('?image=', $dats);
$idImgs[] = substr($datFiltered[1], 0, -1);
}
}
to something like
if (preg_match('/^\?image=(rId|opentbs)/', $datsFiltered[1])) { // <--this is line 239
Since all images switched in by OpenTBS use opentbs as a prefix to avoid conflicts with existing elements.
I'm no regular expression expert, so lets call this pseudo code. Hope it points you in the right direction at least.

Categories