Adding multiple images in excel using PhpSpreadsheet - phpspreadsheet

This issue is solved with workaround. If I copy multiple images, using PhpSpreadsheet in excel, having same image name and different paths, than only last image is added multiple times. But if I rename images with different names, than it's working fine. Eg, if I copy path1/thumb.png and path2/thumb.png to excel, than path2/thumb.png will be copied two times. But if if I copy, path1/image1.png and path2/image2.png, than it's working fine. Example
<?php
require 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
$spreadsheet = new Spreadsheet();
$name = "image.xlsx";
$writer = new Xlsx($spreadsheet);
$writer->save($name);
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
//$drawing->setPath("path1/thumb.png"); I AM COPING AND UPDATING NAME
copy("path1/thumb1.png","thumb1.png");//WORKAROUND FOR THIS ISSUE
$drawing->setPath("thumb1.png");
$drawing->setName('Logo');
$drawing->setCoordinates('B2');
$drawing->setWidthAndHeight(500, 500);
$drawing->setWorksheet($spreadsheet->setActiveSheetIndex(0));
$writer->save( $name );
$writer2 = new Xlsx($spreadsheet);
$writer2->save($name);
$writer2 = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$drawing1 = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
//$drawing->setPath("path2/thumb.png"); THIS WILL OVERWRITE ABOVE path1/thumb1.png, and will be inserted twice.
copy("path2/thumb1.png","thumb2.png");//WORKAROUND FOR THIS ISSUE
$drawing1->setPath("thumb2.png");
$drawing->setName('New image');
$drawing1->setCoordinates('B24');
$drawing1->setWidthAndHeight(500, 500);
$drawing1->setWorksheet($spreadsheet->setActiveSheetIndex(0));
$writer2->save( $name );
?>
...

You overwrite with
$writer2 = new Xlsx($spreadsheet);
the first image.
Try
<?php
require 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
$spreadsheet = new Spreadsheet();
$name = "image.xlsx";
$writer = new Xlsx($spreadsheet);
$writer->save($name);
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
$drawing->setPath("thumb1.png");
$drawing->setName('Logo');
$drawing->setCoordinates('B2');
$drawing->setWidthAndHeight(500, 500);
$drawing->setWorksheet($spreadsheet->setActiveSheetIndex(0));
$drawing1 = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
$drawing1->setPath("thumb2.png");
$drawing1->setName('New image');
$drawing1->setCoordinates('B24');
$drawing1->setWidthAndHeight(500, 500);
$drawing1->setWorksheet($spreadsheet->setActiveSheetIndex(0));
$writer->save( $name );
?>

Related

TCPDF how do I create several pdf's without opening a browser

I need to create like 350 pdf's at once. Now the browser opens a window for each pdf. I takes longer to open all the 350 windows than to create the pdf's. How do I create and save the pdf's without opening a browser windows? (In my pdf I use Header, body and footer all with variables)
Now I do a loop on php_page_1 which opens the pdf create file.
$sql = "SELECT id FROM shipping_id WHERE datum BETWEEN $date_range AND acc_id=$acc_id;";
$STH = $dbo->prepare( $sql );
$STH->execute();
$contains_files = 0;
$client_id='';
while ( $row = $STH->fetch( PDO::FETCH_ASSOC ) ) {
$contains_files++;
$link = "vb_print_1_no_screen.php?id=" . $row[ 'id' ] . "&nr=".$contains_files;
echo '<script>window.open("https://' . $website_admin . $link . '");</script>';
}
You can use curl to make the request to the URL instead of opening it directly in the browser or you can just include the file that generates the PDF. Try this code
$sql = "SELECT id FROM shipping_id WHERE datum BETWEEN $date_range AND acc_id=$acc_id;";
$STH = $dbo->prepare( $sql );
$STH->execute();
$contains_files = 0;
$client_id='';
while ( $row = $STH->fetch( PDO::FETCH_ASSOC ) ) {
$contains_files++;
$link = "vb_print_1_no_screen.php?id=" . $row[ 'id' ] . "&nr=".$contains_files;
// echo '<script>window.open("https://' . $website_admin . $link . '");</script>';
// method 1 using curl
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $website_admin . $link);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$return = curl_exec($ch);
curl_close($ch);
// method 2 include pdf generator script
$_GET['id'] = $row['id'];
$_GET['nr'] = $contains_files;
include "vb_print_1_no_screen.php";
}
Kindly make sure to use just one method.

PHPSpreadsheet --> How to delete a single image/drawing

I use PHPSpreadsheet to open an Excel-Sheet and exchange an image in cell A27.
My actual code doesn't replace the image but add it as overlay to the existing image:
$inputFileName = $_SERVER['DOCUMENT_ROOT']."output/test.xlsx";
$spreadsheet = $reader->load($inputFileName);
$sheet = $spreadsheet->getActiveSheet();
// Remove old image --> Fails
$sheet->setCellValue("A27", "");
echo "Bild ".$pfad_bild." in Zelle ".$zelle." einfügen<br>";
$image_placer = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
$image_placer->setName("myimg");
$image_placer->setDescription("myimg");
$image_placer->setPath("path/to/new/image");
$image_placer->setHeight(500);
$image_placer->setCoordinates('A27');
$image_placer->setOffsetX(0);
$image_placer->setOffsetY(0);
$image_placer->setWorksheet($spreadsheet->getActiveSheet());
// Save file with new tmp-name
$writer = new Xlsx($spreadsheet);
$writer->save($inputFileName."_");
// Delete old file
unlink($inputFileName);
// Rename new file to correct name
rename($inputFileName."_", $inputFileName);
Does anyone has an idea how to delete the Image from the Cell?
Here's the answer, i actually found out:
global $reader;
$reader = IOFactory::createReader('Xlsx');
function exchange_image_within_cell($path_file,$cell,$path_img) {
global $reader;
$inputFileName = $_SERVER['DOCUMENT_ROOT'].$path_file;
$spreadsheet = $reader->load($inputFileName);
$bilder_array=$spreadsheet->getActiveSheet()->getDrawingCollection();
$bilder_array_copy = $bilder_array->getArrayCopy();
$i = 0;
foreach ($bilder_array_copy as $drawing) {
$coordinates=$drawing->getCoordinates();
if ($coordinates==$cell) {
// Delete Image from Array/Cell
unset($bilder_array_copy[$i]);
}
$i++;
}
// Reorder and exchange array
$bilder_array_copy = array_values($bilder_array_copy);
$bilder_array->exchangeArray($bilder_array_copy);
$sheet = $spreadsheet->getActiveSheet();
// Place new image
$sheet->setCellValue($cell, "");
$image_placer = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
$image_placer->setName($path_img);
$image_placer->setDescription($path_img);
$image_placer->setPath($path_img);
$image_placer->setHeight(500);
$image_placer->setCoordinates(''.$cell.'');
$image_placer->setOffsetX(0);
$image_placer->setOffsetY(0);
$image_placer->setWorksheet($spreadsheet->getActiveSheet());
// Save file with new tmp-name;
$writer = new Xlsx($spreadsheet);
$writer->save($inputFileName."_");
// Delete old file
unlink($inputFileName);
// Rename new file
rename($inputFileName."_", $inputFileName);
}
Daniel's answer is correct, but is not brief at all. Basically, once you know the index $i of the drawing to be removed from the worksheet $sheet, you can use:
$drawings = $sheet->getDrawingCollection();
unset($drawings[$i]);

Embedded image in SendGrid email

I am managing to send mails just fine with send grid, attachment too no issues. But I am having problems embedding images into the body of the HTML mail
Here is the code that I am using, put together after reading various examples on this issue. Anyone know where I am going wrong, regards...
MemoryStream msLogo = new MemoryStream(obj.logo);
Bitmap b = new Bitmap(msLogo);
ImageConverter ic = new ImageConverter();
Byte[] ba = (Byte[])ic.ConvertTo(b, typeof(Byte[]));
MemoryStream logo = new MemoryStream(ba);
AlternateView htmlView = AlternateView.CreateAlternateViewFromString(sBody, null, "text/html");
LinkedResource imageResource = new LinkedResource(logo);
var imagelink = new LinkedResource(logo, "image/png");
imagelink.ContentId = string.Format("logo", myMessage);
imagelink.TransferEncoding = TransferEncoding.Base64;
b.Save(logo, ImageFormat.Jpeg);
logo.Position = 0;

how to set the correct path for file download in zendframework2

my controller:
public function downloadAction()
{
$param['filename'] = $this->params()->fromRoute('filename');
$param['foldername'] = $this->params()->fromRoute('foldername');
$fileName = $param['filename']; //bala.pdf
$folderName = $param['foldername']; //j1005
$fileContents = file_get_contents($fileName);
$response = $this->getResponse();
$response->setContent($fileContents);
$headers = $response->getHeaders();
$headers->clearHeaders()
->addHeaderLine('Content-Type', 'application/pdf')
->addHeaderLine('Content-Disposition', 'attachment; filename="' .$fileName . '"')
->addHeaderLine('Content-Length', strlen($fileContents));
return $this->response;
}
my file location is ./data/basepaper/j1005/bala.pdf , but i dont know how to set the path for download the file
It could be good for you to assign your variable properly (initialise empty array for instance before use) and to use your variables (the array is only used to assign the variables again...).
Concerning the current problem, you need to understand the basic of the file management on ZF2, and therefore read the index.php:
<?php
/**
* This makes our life easier when dealing with paths. Everything is relative
* to the application root now.
*/
chdir(dirname(__DIR__));
Which means you can refer to any file from the root directory of your project.
So your code become:
public function downloadAction()
{
// Combine assignation (unused array, and non initialised...)
$fileName = $this->params()->fromRoute('filename');
$folderName = $this->params()->fromRoute('foldername');
$fileContents = file_get_contents("data/basepaper/{$folderName}/{$fileName}");
$response = $this->getResponse();
$response->setContent($fileContents);
$headers = $response->getHeaders();
$headers->clearHeaders()
->addHeaderLine('Content-Type', 'application/pdf')
->addHeaderLine('Content-Disposition', 'attachment; filename="' .$fileName . '"')
->addHeaderLine('Content-Length', strlen($fileContents));
return $this->response;
}

Streaming Word Doc in OpenXML SDK using ASP.NET MVC 4 gets corrupt document

I am trying to do this on ASP.NET MVC 4:
MemoryStream mem = new MemoryStream();
using (WordprocessingDocument wordDoc =
WordprocessingDocument.Create(mem, DocumentFormat.OpenXml.WordprocessingDocumentType.Document, true))
{
// instantiate the members of the hierarchy
Document doc = new Document();
Body body = new Body();
Paragraph para = new Paragraph();
Run run = new Run();
Text text = new Text() { Text = "The OpenXML SDK rocks!" };
// put the hierarchy together
run.Append(text);
para.Append(run);
body.Append(para);
doc.Append(body);
//wordDoc.Close();
///wordDoc.Save();
}
return File(mem.ToArray(), "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "ABC.docx");
However the ABC.docx opens as corrupted and it wouldn't open even after fixing it.
Any ideas?
Linked Qs:
Streaming In Memory Word Document using OpenXML SDK w/ASP.NET results in "corrupt" document
Apparently the problem comes from missing this 2 lines:
wordDoc.AddMainDocumentPart();
wordDoc.MainDocumentPart.Document = doc;
Updated the code to below and it now works flawlessly, even without any extra flushing, etc necessary.
MemoryStream mem = new MemoryStream();
using (WordprocessingDocument wordDoc =
WordprocessingDocument.Create(mem, DocumentFormat.OpenXml.WordprocessingDocumentType.Document, true))
{
wordDoc.AddMainDocumentPart();
// instantiate the members of the hierarchy
Document doc = new Document();
Body body = new Body();
Paragraph para = new Paragraph();
Run run = new Run();
Text text = new Text() { Text = "The OpenXML SDK rocks!" };
// put the hierarchy together
run.Append(text);
para.Append(run);
body.Append(para);
doc.Append(body);
wordDoc.MainDocumentPart.Document = doc;
wordDoc.Close();
}
return File(mem.ToArray(), "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "ABC.docx");

Resources