phpspreadsheet: How to add some margin between a cell and the image? - php

When inserting an image into a cell, it gets inserted to the very left of the cell, I'd like to add some margin, how to do so?
I tried many things, I'm not the first to ask this, it's being asked since the days of PHPexcel and there's no answer, I tried every solution to no avail, like this one, which should center whatever is in the cell, it centers text but not images
function center(){
$styleArray = [
'alignment' => [
'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER,
'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
],
];
return $styleArray;
}
$sheet->getStyle('B2')->applyFromArray(center()));
I'm not necessarily trying to center it, whatever works, all I need is some margin between the cell and the image.

use setOffsetX like this
$drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
$drawing->setWorksheet($spreadsheet->getActiveSheet());
$drawing->setPath('../assets/img/logo.png');
$drawing->setWidthAndHeight(158, 72);
$drawing->setResizeProportional(true);
$drawing->setOffsetX(10); // this is how
$drawing->setOffsetY(3); // this is how

Related

How to change font size when using PhpWord TemplateProcessor?

Is it possible to change font size when using TemplateProcessor?
I was try to do this, but not working.
$template = new PhpOffice\PhpWord\TemplateProcessor('template.docx');
$template->setValues([
'name' => 'Nur Muhammad',
'country' => 'Indonesia'
]);
$template->saveAs('result1.docx');
// Try to change the font size
$phpword = PhpOffice\PhpWord\IOFactory::load('result1.docx');
$phpword->setDefaultFontSize(9);
$phpword->save('result2.docx');
The problem I get:
The document styles is lose
The font size doesn't change
Thanks in advance.

Zebra Stripping with phpspreadsheet

I was looking around for examples and/or guides on how to use phpspreadsheet's conditional formatting. Specifically looking so that I could zebra stripe my spreadsheet in a way that allows for resorting of the sheet. I came up very empty with only a few spotty SO questions using the old PHPExcel library and just one example from the documentation. Given that zebra stripes are pretty common style to apply I was mildly outraged that I couldn't find a copy/paste job. So I figured it out myself and now will leave it here for posterity and hopefully myself in a few years.
I am actually going to spell out a lot more as I have used phpspreadsheet for a few years now and out of the box the defaults don't really give you a nice looking spreadsheet. I will also note I do not care how it looks; its just data to me but, my bosses must have quality formatting.
Zebra Stripping
$range = 'A3:'.$spreadsheet->getActiveSheet()->getHighestDataColumn.
$spreadsheet->getActiveSheet()->getHighestDataRow();
$conditional1 = new \PhpOffice\PhpSpreadsheet\Style\Conditional();
$conditional1->setConditionType(\PhpOffice\PhpSpreadsheet\Style\Conditional::CONDITION_EXPRESSION)
->setOperatorType(\PhpOffice\PhpSpreadsheet\Style\Conditional::OPERATOR_EQUAL)
->addCondition('MOD(ROW(),2)=0');
$conditional1->getStyle()->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
->getStartColor()->setARGB('DFDFDF');
$conditional1->getStyle()->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
->getEndColor()->setARGB('DFDFDF');
$spreadsheet->getActiveSheet()->getStyle($range)->setConditionalStyles([$conditional1]);
The range starts at A3 because I have a logo in row 1 and headers in row 2. Also you can apply as many conditions as you need which is why the final setConditionalStyles is wrapped in an array.
Freeze 1 columns and 2 rows
$sheet->freezePane('B2');
This will freeze that cell B2 and everything to the left and above. Super helpful for long and wide sheets letting you keep your primary_key and headers in view at all times.
Insert Logo in 1st cell
$spreadsheet->getActiveSheet()->insertNewRowBefore(1, 1);
$drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
$drawing->setCoordinates('A1');
$drawing->getShadow()->setVisible(true);
$drawing->setName({{alt text}});
$drawing->setPath(resource_path().{{filepath}});
$drawing->setWorksheet($spreadsheet->getActiveSheet());
$spreadsheet->getActiveSheet()->getRowDimension('1')->setRowHeight(55);
Hiding a sheet
$spreadsheet->getActiveSheet()->setSheetState('veryHidden');
This is one thing I really like to do as I have written some automation that relies on a user making
edits to a spreadsheet and returning the sheet to a specific email address that I can access via api and download and reprocess based on the edits to the sheet. I use this mainly for storing information our erp needs to access records such as a customer_id or contract_number so that when the sheet comes back I don't have to re-query ident info I can just grab it from the hidden sheet. Bonus of using very hidden is a normal user can't unhide it unless they know enough to open the dev window and get in VB script.
Put Filters on all headers
$dimensions = 'A2' . ':' . $spreadsheet->getActiveSheet()->getHighestDataColumn() .
$spreadsheet->getActiveSheet()->getHighestDataRow();
$spreadsheet->getActiveSheet()->setAutoFilter($dimensions);
$autoFilter = $spreadsheet->getActiveSheet()->getAutoFilter();
$autoFilter->showHideRows();
The trick on this one is the last line it won't actually apply the filters until there is some kind of action so I just grabbed a random function that wouldn't have any effect on my sheet.
Auto Width Columns
$colNumber = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString(
$spreadsheet->getActiveSheet()->getHighestDataColumn);
for ($col = 1; $col <= $colNumber; $col++) {
$colAlpha = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($col);
$spreadsheet->getActiveSheet()->getColumnDimension($colAlpha)->setAutoSize(true);
}
$sheet->calculateColumnWidths();
Making Spreadsheets with multiple tabs
First let me note I have come up with a somewhat standard structure I use whenever I make a spreadsheet and then I feed it through one function that does all of the above things. So here is my standard.
$report = json_encode([
'filepath' => 'Program Size/',
'filename' => $customer_name->company_name.' Program Size '.Carbon::parse('now')->format('Ymd').'.xlsx',
'Type' => 'buildMultiSheet',
'1' => [
'request' => [
'TabName' => 'Program Size',
'header' => array_keys($source[0]),
'body' => $source,
'formatArray'=> [
'aboveHeader'=>['Total Value:',$sum],
'zebra' => 'stripe',
'F:G' => '"$"#,##0.00_-'
]
]
],
'2' => [
'request' => [
'TabName' => 'config_sheet',
'header' => [],
'body' => $queryLog,
'formatArray'=> [
'hidden'=> 1
]
]
]
]);
This structure has every thing you need to make a spreadsheet with multiple tabs. Source for me is generally the result of a DB call. This isn't complete detail for example a tabname longer than 31 characters will freak out so you have to check for it. One of these days I might tidy things up and publish a package to go along side phpspreadsheet but, we will see if/when that ever happens.
$spreadsheet = new Spreadsheet();
$filename = $requestD["filename"];
unset($requestD["filename"]);
$filepath = $requestD["filepath"];
unset($requestD["filepath"]);
$tabCounter = 0;
$spreadsheet->setActiveSheetIndex($tabCounter);
foreach ($requestD as $tab) {
$sheet = $spreadsheet->getActiveSheet();
$body = $tab["request"]["body"];
$spreadsheet->getActiveSheet()->setTitle($tab["request"]["TabName"]);
$headers = $tab["request"]["header"];
$sheet->fromArray($headers, NULL, 'A1');
$sheet->fromArray($body, NULL, 'A2', false);
//processing here, sheet formatting , etc.
$tabCounter++;
$spreadsheet->createSheet();
$spreadsheet->setActiveSheetIndex($tabCounter);
}
//remove last empty sheet before resetting index
$spreadsheet->setActiveSheetIndex(0);
$spreadsheet->removeSheetByIndex($tabCounter);
Well that's all the tips I have. If I have done anything really dumb please do let me know how I can improve.

TYPO3 TCA value as a variable on Fluid

I have a base extension so i can version my website. That means i have not a controller or a repository on the extension. So what i want to do, is to create my own settings on existing elements. I was experimenting around with a text align values on the header content element.
Keep in mind, there is already a setting for this, but i am just
experimenting.
I figured out how to add them and the values are saved on the database.
What i now want to do, is to take the values and add them as a class on FLUID. This is where i stuck. I can not get the values. Any idea how to do it?
After this guide How to enable header_position in TYPO3 7.6
i manage to get my code that far:
On the folder /Configuration/TCA/Overrides/tt_content.php
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
ExtensionManagementUtility::addTCAcolumns('tt_content',[
'header_position_custom' => [
'exclude' => 1,
'label' => 'header position',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'items' => [
['left', 'left'],
['right', 'right'],
['center', 'center']
]
]
]
]);
ExtensionManagementUtility::addFieldsToPalette('tt_content', 'header', '--linebreak--,header_position_custom', 'after:header_layout');
ExtensionManagementUtility::addFieldsToPalette('tt_content', 'headers', '--linebreak--,header_position_custom', 'after:header_layout');
On the folder /Configuration/Typoscript/Constants/Base.typoscript
styles.templates.templateRootPath = EXT:my_website_base/Resources/Private/Extensions/Fluid_styled_content/Resources/Private/Templates/
styles.templates.partialRootPath = EXT:my_website_base/Resources/Private/Extensions/Fluid_styled_content/Resources/Private/Partials/
styles.templates.layoutRootPath = EXT:my_website_base/Resources/Private/Extensions/Fluid_styled_content/Resources/Private/Layouts/
On the /Resources/Private/Extensions/Fluid_styled_content/Resourcs/Private/Partials/Header.html
<h1 class="{positionClass} {header_position_custom} {data.header_position_custom} showed">
<f:link.typolink parameter="{link}">{header}</f:link.typolink>
</h1>
I 've put the class showed just to make sure that i am reading the
file from the path i gave on the constants
File ext_tables.php
TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile($_EXTKEY,'Configuration/TypoScript', 'Website Base');
File ext_tables.sql
CREATE TABLE tt_content (
header_position_custom varchar(255) DEFAULT '' NOT NULL,
);
With all these i get my selectbox where i wanted to be and i get the values on the database. That means that if i select the value "Center" in the selectbox, then it will be saved on the database. How can i get this value and use it as class on the FLUID?
Thanks in advance,
You will find your field in the data object.
For inspecting your fluid variables you can use the f:debug-VH:
<f:debug title="the data">{data}</f:debug>
for inspecting all (in the current context) available variables you can debug _all:
<f:debug title="all data">{_all}</f:debug>
Hint: use the title attribute to identify the output
and don't forget to write a get* and set* function for new fields!

mPDF: how to remove setHeader() & setFooter() borders

i have a mPDF report on my system and in the report, it has a header and footer where i use $mpdf->setHeader(); & $mpdf->setFooter(); to set the header and footer. but it displays a bottom border for header and top border for footer. can anyone help me how to remove this?
heres the image:
Here's my Code:
$mpdf=new mPDF('','LETTER-L','','',35,35,60,25,10,10);
//left margin, right margin, body, top margin,top margin,bottom margin,
/*HEADER Monthly Accomplishment Report*/
$mpdf->SetHeader('Sample');
/*FOOTER xMonthly Accomplishment Report*/
$mpdf->SetFooter('Sample');
//==============================================================
//=====================FILE DESCRIPTION=========================
//==============================================================
$mpdf->SetTitle('Monthly Accomplishment Report');
$mpdf->SetSubject('Report');
$mpdf->SetAuthor('sample');
$mpdf->Output('sample.pdf','I');
exit;
//==============================================================
//==============================================================
//==============================================================
You could use those two mpdf properties instead:
$mpdf->defaultheaderline = 0;
$mpdf->defaultfooterline = 0;
I had a look at the documentation of the method setHeader and found that exists a line parameter :
$line: specify whether to draw a line under the Header
You passed a string to the method but it also accept an array of options.
$line mentionned in the doc is not exactly a parameter of the method, rather a key of the configuration array.
So this code should accomplish what you look for, based on the documentation:
$mpdf = new mPDF('','LETTER-L','','',35,35,60,25,10,10);
$headerFooterContent = 'Sample';
$oddEvenConfiguration =
[
'L' => [ // L for Left part of the header
'content' => '',
],
'C' => [ // C for Center part of the header
'content' => '',
],
'R' => [
'content' => $headerFooterContent,
],
'line' => 0, // That's the relevant parameter
];
$headerFooterConfiguration = [
'odd' => $oddEvenConfiguration,
'even' => $oddEvenConfiguration
];
$mpdf->SetHeader($headerFooterConfiguration);
$mpdf->SetFooter($headerFooterConfiguration);
The setHeader and setFooter methods accept the same arguments (they are almost copy/pasted in the library).
I let you look further at the specific part of the examples related to complex header configuration of mPDF.
Let me know if it solves your issue.
Depending on the version of mpdf, you can use this:
$pdf->options['defaultheaderline'] = 0;
$pdf->options['defaultfooterline'] = 0;

How can reduce height and download pdf using FPDF?

I have a function to generate pdf using Fpdf in laravel.
My problems are:
After all Cell I have some extra space. I need to remove that. Please find the image given below.
How can I download this pdf file in to my system. Currently it's just showing in to browser. Code samples are given below.
Code
Controller: Controller.php
public function index()
{
$orders = Order::select('firstname', 'lastname', 'street', 'postal', 'country')->get();
foreach ($orders as $order){
Fpdf::SetMargins(5, 5, 5);
Fpdf::AddPage('L', array(60,90), 'A4');
Fpdf::SetAutoPageBreak(TRUE, 0);
Fpdf::SetFont('helvetica', '', 7); //IF bold letter SetFont('Arial','B',14)
Fpdf::SetTextColor(0, 0, 0);
Fpdf::Cell(10,5,iconv('UTF-8', 'windows-1252', 'Falls unzustellbar, zurück an Absender'),0,"1","L");
Fpdf::SetFont('','U');
Fpdf::Cell(10,5,iconv('UTF-8', 'windows-1252', 'schrillALARM.jetzt c/o 365group • Grasgasse 2 • 93047 Regensburg'),0,"1","L");
Fpdf::SetFont('helvetica', '', 11);
Fpdf::Cell(10,5,$order->firstname,0,1,"L");
Fpdf::Cell(10,5,$order->lastname,0,1,"L");
Fpdf::Cell(10,5,$order->street,0,1,"L");
Fpdf::Cell(10,5,$order->postal,0,1,"L");
Fpdf::Cell(10,5,$order->country,0,1,"L");
}
Fpdf::Output();
exit;
}
Route: Route::get('/test', 'Controller#index');
No experience with FDPF, but you can download this way:
Route::get(
'download/pdf/{pdf}',
function ($pdf) {
$file = // Get file
return response()->download($file);
}
);
Or just from your controller with
return response()->download($pdf);
for saving, just specify output path and filename in your output call string
Fpdf::Output([string dest [, string name [, boolean isUTF8]]])
For your white space though, when you're constructing your PDF document, you can use a default size of one of the following: A3, A4, A5, Letter, Legal with A4 being default. However, you can also declare custom sizes. This is more than likely what you're looking for, as you'll want to play with the sizes to get it with the amount of white space you're looking for. FPDF puts out the canvas first then fills it, so you're white space is coming from a canvas that is too big. This can be done in the constructor, or AddPage as you have done.
VIA Constructor:
//(L)andscape or (P)ortrait, unit type (mm millimeters), array size in mm
$pdf = new FPDF('L','mm',array(100,150));
VIA AddPage (must likely what you're looking for):
currently you have:
Fpdf::AddPage('L', array(60,90), 'A4');
however, params are supposed to be landscape/portrait, Predefined or custom size array, then rotation. So try this:
Fpdf::AddPage('L', array(60,90));
Now you'll need to play with those numbers, more than likely the 90, and shorten that up to rid yourself of the white space.

Categories