I am trying to generate Excel document using PHPExcel library.
class product_specification_order extends DBHelper
{
static $PK = 'orderID';
static function xls($id){
require_once('../lib/PHPExcel.php');
$objPHPExcel = new PHPExcel();
$objPHPExcel->setActiveSheetIndex(0);
return $objPHPExcel;
}
}
Then, I have generatespecxls.php file
if (empty($_REQUEST['id']))
die("Wrong ID");
//output xls
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");;
header("Content-Disposition: attachment;filename=File.xls");
header("Content-Transfer-Encoding: binary");
$objPHPExcel = product_specification_order::xls($_REQUEST['id']);
$objWriter = new PHPExcel_Writer_Excel5($objPHPExcel); // (I want the output for objWriter)
///print_r($objWriter);
$objWriter->save('php://output');
The output I get is rubbish.
Related
I'm looking for a solution to this issue for a long time.
This is an img => https://www.siweb.es/images/logo-light.png
I want to store this image as zip file usin OneupUploaderBundle.
So, when i get the image from Url usin file_get_contents or CURL it returns the image correctly but when i pass this file to $zip->addFile(); or an uoload service using Symfony\Component\HttpFoundation\File\UploadedFile both returns an error cause they are receiving a string as first Parameter.
I guess the problem is the file is not an instanceOf UploadeFile but i don't know how to convert it or use Filebag without a form.
public function testAction(Request $request){
$term = 'https://www.siweb.es/images/logo-light.png';
$image = $this->getimg($term);
if ($image instanceof UploadedFile){
$upload = $this->get('pablo.file_upload_service')->uploadZipFile($image,'test');
}
return $this->render('#pabloUser/Test/zip_test.html.twig',['upload' => $image]);
}
private function getimg($url) {
$headers[] = 'Accept: image/gif, image/x-bitmap, image/jpeg, image/pjpeg';
$headers[] = 'Connection: Keep-Alive';
$headers[] = 'Content-type: application/x-www-form-urlencoded;charset=UTF-8';
$user_agent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)';
$process = curl_init($url);
curl_setopt($process, CURLOPT_HTTPHEADER, $headers);
curl_setopt($process, CURLOPT_HEADER, 0);
curl_setopt($process, CURLOPT_USERAGENT, $user_agent);
curl_setopt($process, CURLOPT_TIMEOUT, 30);
curl_setopt($process, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($process, CURLOPT_FOLLOWLOCATION, 1);
$return = curl_exec($process);
curl_close($process);
return $return;
}
And the service:
public function uploadZipFile(UploadedFile $file,$folder){
// Check if the file's mime type is in the list of allowed mime types.
if (!in_array($file->getClientMimeType(), self::$allowedMimeTypes)) {
$this->pushbulletService->notification('Error en la subida de archivos',sprintf('Files of type %s are not allowed.', $file->getClientMimeType()));
throw new \InvalidArgumentException(sprintf('Files of type %s are not allowed.', $file->getClientMimeType()));
}
// Generate a unique filename based on the date and add file extension of the uploaded file
$filename = sprintf('%s/%s.%s', $folder, uniqid(), $file->getClientOriginalExtension());
$zipname = 'file.zip';
$zip = new \ZipArchive();
$zip->open($zipname,\ZipArchive::CREATE);
$zip->addFile($file);
$zip->close();
$adapter = $this->filesystem->getAdapter();
$adapter->write($filename, $zipname);
return $filename;
}
The problem is that your result from getimg is a (binary) string containing the image data. In order to pass it on as an UploadedFile you have to store the image in a (temporary) file first and then pass the path to it in the constructor.
It could look something like this:
$data = $this->getimg(...);
file_put_contents(sys_get_temp_dir() . '/filename.jpg', $data);
$image = new UploadedFile(
sys_get_temp_dir() . '/logo-light.png',
'logo-light.png'
);
$upload = $this->get('pablo.file_upload_service')->uploadZipFile($image,'test');
Without Symfony, this is how I post excel data to database.
// Include PHPExcel_IOFactory
require_once ('../Classes/PHPExcel/IOFactory.php');
$inputFileName = 'abc.xls';
// Read your Excel workbook
try {
$inputFileType = PHPExcel_IOFactory::identify($inputFileName);
$objReader = PHPExcel_IOFactory::createReader($inputFileType);
$objPHPExcel = $objReader->load($inputFileName);
} catch(Exception $e) {
die('Error loading file "'.pathinfo($inputFileName,PATHINFO_BASENAME).'": '.$e->getMessage());
}
// Get worksheet dimensions
$sheet = $objPHPExcel->getSheet(0);
$highestRow = $sheet->getHighestRow();
$highestColumn = $sheet->getHighestColumn();
// Loop through each row of the worksheet in turn
for ($row = 1; $row <= $highestRow; $row++){
// Read a row of data into an array
$rowData = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row,
NULL,
TRUE,
FALSE);
// Insert row data array into your database of choice here
}
Now with the ExcelBundle, I am stuck. The documentation doesn't help me at all in this task. I've tried every advice given in similar questions and I cant manage to do this.
Creating an object from a file like the example below doesn't work at all:
$phpExcelObject = $this->get('phpexcel')->createPHPExcelObject('file.xls');
How to achieve this task?
I worked this out as follows:
Make sure the path Liuggio/ExcelBundle/Controller/FakeController.php exists
Make sure you update the app/config config.yml and routing.yml are updated with the provided files (Liuggio/ExcelBundle/Tests/app)
Assuming that you are updating the product table, Update the FakeController as follows:
<?php
namespace Liuggio\ExcelBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use AppBundle\Entity\Product;
class FakeController extends Controller
{
public function insertAction()
{
$data = [];
$appPath = $this->container->getParameter('kernel.root_dir');
$file = realpath($appPath . '/../web/excelFiles/abc.xls');
$phpExcelObject = $this->get('phpexcel')->createPHPExcelObject($file);
$sheet = $phpExcelObject->getActiveSheet()->toArray(null, true, true, true);
$em = $this->getDoctrine()->getManager();
$data['sheet'] = $sheet;
//READ EXCEL FILE CONTENT
foreach($sheet as $i=>$row) {
if($i !== 1) {
$product = new Product();
$product->setProductCode($row['A']);
$product->setProductName($row['B']);
$product->setProductRetailPrice($row['C']);
$product->setProductCost($row['D']);
$product->setProductTax($tax);
$product->setCategory($category);
//... and so on
$em->persist($product);
$em->flush();
//redirect appropriately
}
}
$data['obj'] = $phpExcelObject;
return $this->render('excel/read.html.twig', ['data' => $data ] );
}
}
I am virtually at a brick wall with Symfony, I have a folder at /../compiled/ with some minified files, and the controller is configured to get files from getRootDir() + /../compiled/file.min.css
However, it just throws out an exception 'file not found' when call file_get_contents(file) even when the file actually exists.
I just don't know what is wrong, it is such a cryptic problem.
Code as requested:
public function atpInitAction(Request $request) // Validates the origin.
{
$content = null; $_file = $request->query->get('file');
if ($_SERVER["SERVER_NAME"] == atpHandler::getDomain())
{
// I AM FROM THE ORIGIN...
$webfolder = $this->get('kernel')->getRootDir() . '/../compiled';
$_file = $webfolder."/".$_file;
}
// What's my mime?
$_mime = 'text/plain';
if ($_file[strlen($_file)-2] == 'j') { $_mime = 'text/javascript'; }
else { $_mime = 'text/css'; }
$response = new Response();
$response->headers->set('Content-Type', $_mime);
$response->headers->set('Content-Disposition', 'filename="'.basename($_file) . '";');
$response->headers->set('Content-Length', filesize($_file));
$response->setContent(file_get_contents($_file));
$response->sendHeaders();
return $response;
}
I've looked at this question but it doesnt work for me.
my controller looks like:
/**
* #Route("/testing")
*/
public function trackingNewsletter() {
$filename = 'T:\wamp\www\trendytouristmx\web\uploads\establishments\1-37.jpg';
$response = new \Symfony\Component\HttpFoundation\Response();
$response->headers->set('Cache-Control', 'private');
$response->headers->set('Content-type', mime_content_type($filename));
$response->headers->set('Content-Disposition',
'attachment; filename="' . basename($filename) . '";');
$response->headers->set('Content-length', filesize($filename));
$response->sendHeaders();
$response->setContent(file_get_contents($filename));
return $response;
}
But in the browser code is displayed instead of the image displayed:
browser looks like this
Thank you.
There is a special class which is designed for binary file response. I would recommend to use it instead. More info BinaryFileResponse
//$filePath = ...
//$filename = ...
$response = new BinaryFileResponse($filePath);
$response->trustXSendfileTypeHeader();
$response->setContentDisposition(
ResponseHeaderBag::DISPOSITION_INLINE,
$filename,
iconv('UTF-8', 'ASCII//TRANSLIT', $filename)
);
return $response;
You have to do :
public function trackingNewsletter() {
$path = 'T:\wamp\www\trendytouristmx\web\uploads\establishments\1-37.jpg';
$response = new Symfony\Component\HttpFoundation\Response();
$response->headers->set('Content-type', mime_content_type($path));
$response->headers->set('Content-length', filesize($path));
$response->sendHeaders();
$response->setContent(readfile($path));
}
Thank you #chalasr, finally it works, here's a solution:
first, I removed $response->headers->set('Cache-Control', 'private');
second, I changed the value of Content-Disposition from attachment to inline.
/**
* #Route("/tracking")
*/
public function trackingnewsletterAction() {
$filename = '...\establishments\1-39.jpg';
$response = new \Symfony\Component\HttpFoundation\Response();
$response->headers->set('Content-type', mime_content_type($filename));
$response->headers->set('Content-Disposition',
'inline; filename="' . basename($filename) . '";');
$response->headers->set('Content-length', filesize($filename));
$response->sendHeaders();
$response->setContent(file_get_contents($filename));
return $response;
}
I have regular Drupal Commerce setup with installed Feeds, Feeds Tamper and Commerce Feeds modules.
Here is tiny piece of the CSV file I'm trying to import:
SKU,Title,Price,Sizes,Model
JKR122/1,Red T-Shirt,44,"42,44,46",JKR122
JKR122/2,Blue T-Shirt,44,"42,44,46",JKR122
Is it possible using Feeds Tamper, to explode "Sizes" column and import each as separate product. Probably it will be needed to append exploded size to SKU.
I'm no pro in Excel, so if it is possible to easily reformat this huge CSV file, please tell me how.
As problem had to be solved today, I wrote PHP-script which reformats my CSV:
I'll leave question opened, in case anuone knows if this can be done by "Drupal-way".
<?php
define('ATTR_SIZE', 'Sizes');
define('ATTR_SKU', 'SKU');
define('IMPORT_FILE', 'import_file.csv');
define('EXPORT_FILE', 'export_file.csv');
define('CSV_DELIMITER', ',');
// Open csv
if(!file_exists(IMPORT_FILE) || !is_readable(IMPORT_FILE))
die('Check file');
$header = NULL;
$all_rows = array();
if (($handle = fopen(IMPORT_FILE, 'r')) !== FALSE) {
while (($row = fgetcsv($handle, 1000, CSV_DELIMITER)) !== FALSE) {
if (!$header)
$header = $row;
else
$all_rows[] = array_combine($header, $row);
}
fclose($handle);
}
// Process csv
$new_rows = array();
foreach ($all_rows as $key => $row) {
if (!empty($row[ATTR_SIZE])) {
$original_row = $row;
$sizes = explode(',', $row[ATTR_SIZE]);
foreach ($sizes as $size) {
$trimmed_size = trim($size);
if (!empty($trimmed_size)) {
$row = $original_row;
$row[ATTR_SIZE] = $trimmed_size; // Save size
$row[ATTR_SKU] = $row[ATTR_SKU] . '/' . $trimmed_size; // Modify SKU
$new_rows[] = $row; // Add new row
}
}
}
else {
$new_rows[] = $row;
}
}
// Save csv
$header = NULL;
$handle = fopen(EXPORT_FILE, 'w');
foreach ($new_rows as $fields) {
if (!$header) {
fputcsv($handle, array_keys($fields));
$header = TRUE;
}
fputcsv($handle, $fields);
}
fclose($handle);