I am creating table using phpword and add to template. In output file, The table column are reverse in order. I have create cell correctly.
<?php
$data=[
['cell 1 row 1','cell 2 row 1'],
['cell 1 row 2','cell 2 row 2']
];
//phpword
require_once '../vendor/autoload.php';
use PhpOffice\PhpWord\TemplateProcessor;
use PhpOffice\PhpWord\IOFactory;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\SimpleType\TblWidth;
use PhpOffice\PhpWord\Style\Table;
use PhpOffice\PhpWord\Writer\Word2007\Element\Container;
use PhpOffice\PhpWord\Shared\XMLWriter;
$fontStyle = new \PhpOffice\PhpWord\Style\Font();
$fontStyle->setName('Times');
$phpWord = new PhpWord();//phpword object
$section = $phpWord->addSection();//section
$tbl = $section->addTable(array(
/*'ltr' => true,*/
/*"layout" => Table::LAYOUT_AUTO,
"width" => 100 * 50, //in word 1% == 50 unit (with in 1/50)
"unit" => TblWidth::PERCENT,
'lineHeight' => 1*/
));
for($i=0;$i < 40;$i++){
$tbl->addRow();
$tbl->addCell(150)->addText("cell 1 row:$i");
$tbl->addCell(150)->addText("cell 2 row:$i");
$tbl->addCell(150)->addText("cell 3 row:$i");
$tbl->addCell(150)->addText("cell 4 row:$i");
//$tbl->addCell(150)->addMultiLineText("cell\n4 row:$i");
}
$xmlWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY, './', Settings::hasCompatibility());
$containerWriter = new Container($xmlWriter, $section);
$containerWriter->write();
$elXml = $xmlWriter->getData();
// remplace our templateContent
Settings::setOutputEscapingEnabled(false);
$templateProcessor =new TemplateProcessor('testing_tabledirection.docx');
$templateProcessor->setValue('table', $elXml);
Settings::setOutputEscapingEnabled(true);
$pathToSave ='output_tabledirection.docx';
$templateProcessor->saveAs($pathToSave);
?>
The table column order has been fixed by removing empty array as parameter from addTable().
$tbl = $section->addTable(array());
to
$tbl = $section->addTable();
style name should passed to addTable
$table = $section->addTable([$tableStyle]);
Step to define table style
create array and define style for table
$tableStyle = array(
'borderColor' => '006699',
'borderSize' => 6,
'cellMargin' => 50
);
define style to phpword object
$phpWord->addTableStyle('myTable', $tableStyle);
Add style when create table from section
$table = $section->addTable('myTable');
How can I force PhpWord to write at the begin of the next multi-colum ?
I don't think there is a breaker function (such as addTextBreak() or addPageBreak()) for doing this.
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection(array(
'colsNum' => 2,
'colsSpace' => 100,
'breakType' => 'continuous',
));
$table1 = $section->addTable();
//...add rows and cells to table 1
$table2 = $section->addTable();
//...add rows and cells to table 2
As expected, the result of this code snippet is two table stacked on the first multi-colum.
Adding in the code
$section->addPageBreak()
doesn't obviously work.
Any advice on how to solve this problem?
Is it a good option to add some TextBreakers to the bottom of the page for filling the space that remain after the first table?
Thanks!
I searched for a while, there is a simple way to get the page dimensions of a PDF (of each page)?
I'm not clear if TCPDF or FPDF allows that.
function toPixels($value){
//pt=point=0.352777778 mm, mm=millimeter=2.8346456675057350125948125904915 points, cm=centimeter=28.346456675057350125948125904915 points, in=inch=72 points=25.4mm
switch(PDF_UNIT){//http://www.unitconversion.org/unit_converter/typography.html
case "pt": return $value * 1.328352013;
case "mm": return $value * 3.779527559;
case "in": return $value * 96;
case "cm": return $value * 37.795275591;
}
return "TEST";
}
$dimensions = [//PDF_UNIT defaults to millimeters
"margins" => $pdf->GetMargins(),
"width" => $pdf->getPageWidth(),
"height" => $pdf->getPageHeight(),
];
$dimensions["width"] -= $dimensions["margins"]["left"] + $dimensions["margins"]["right"];
$dimensions["height"] -= $dimensions["margins"]["top"] + $dimensions["margins"]["bottom"];
$dimensions["width_pixels"] = toPixels($dimensions["width"]);
$dimensions["height_pixels"] = toPixels($dimensions["height"]);
You are in charge of setting the required Page dimension while creating an pdf object. For example the Fpdf sets per default an A4 Format, you may also adapt it to your current requirements by
new FPDF('P','your Unit [mm]',[width,height])
Those are your dimensions values which apply to every page of your pdf document.
Furhermore you may also set it for each of your page separatelly:
AddPage([string orientation [, mixed size [, int rotation]]]
And least but not last, there are alse the concept of margins, where you may draw your content.
I am using TCPDF library to generate a PDF file dynamically in my Laravel Project.
I have a requirement to create the Table Of Content section dynamic and set the header of each page using Summary titles. And to give link to each items below which will lead user to the start of that section/content.
Example:
My Table Of Content
Summary ............................... 1
Organization & Management Structure.... 5
Credit History......................... 7
Public Records......................... 8
So,
My page 1 should have header as Summary
Page 2 to 4 should have header as Summary(Cont.)
Page 5 => Organization & Management Structure
Page 6 => Organization & Management Structure(Cont.)
Page 7 => History
Page 8 => Public Records
If you can help me by sending some tricks I can use to complete this, it will be a great help. Thanks!
Honestly, what you're describing sounds like the content of example 45 included TCPDF examples where you could get by just using the built-in TOC generator.
Something I didn't like about the example however is it's lack of body text. So I created a simple example with very basic document structure and randomly generated text below. The idea would be that you set a Bookmark right before you begin writing your content for each section and then have the TOC generator do the rest.
Setting the bookmark right before rendering your content makes it so you don't have to calculate the position of the bookmark. By default it'll take it's current position. I use a pre-built array here and very basic output for simplicity's sake.
Notes:
here may be edge cases where the content immediately overflows to the next page without outputting on the current page. I decided that was out of scope for now since you may not encounter it, but figured I'd note the possibility of it happening.
It may seem obvious, but it's worth mentioning anyway: If adding a page before starting your new section, call the Bookmark method after addPage.
You can view the output of my script: here
As mentioned, I based this off example 045 which you can view on the TCPDF example page. You can also use HTML to format the TOC entries made this way, see example 059.
<?php
// Include the main TCPDF library (search for installation path).
// Change this for your installation.
require_once('TCPDF-6.2.17/tcpdf.php');
// create new PDF document
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT,
PDF_PAGE_FORMAT, true, 'UTF-8', false);
// set default monospaced font
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
// set auto page breaks
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
// set image scale factor
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
//These will become the different colors for our TOC labels.
//Main section is a dark blue, sub-section is a lighter blue. This is
//strictly optional, but I kind of like it myself.
$level_colors = array(
0 => array(0, 0, 66),
1 => array(0, 0, 100),
2 => array(0, 0, 130),
);
/**
* Just produces some filler text.
*/
function gen_random_section_text($min = 70, $max = 300) {
$words = array('Iris', 'Daffodil', 'Dandelion', 'Daisy', 'Orchid', 'Lily',
'Rhododendron', 'Sakura', 'Blossom', 'Larkspur', 'Anemone', 'Hydrangea');
$word_max_index = count($words)-1;
$word_count = rand($min, $max);
$output = array();
for($i = 0; $i < $word_count; $i++) {
$output[] = $words[rand(0, $word_max_index)];
}
return implode(' ', $output);
}
// ---------------------------------------------------------
// set font
$pdf->SetFont('times', '', 14);
/**
* I'll build our list of sections outright for this example.
*/
$sections[] = array(
'title' => 'Summary',
'content' => '<p>'.gen_random_section_text(20,30).'</p>',
'level' => 0,
);
$sections[] = array(
'title' => 'Organization & Management',
'content' => '<p>'.gen_random_section_text(100,200).'</p>'.
'<p>'.gen_random_section_text(120,230).'</p>',
'level' => 0,
);
$sections[] = array(
'title' => 'Hiring Procedures',
'content' => '<p>'.gen_random_section_text(100,200).'</p>',
'level' => 1,
);
$sections[] = array(
'title' => 'In Absence of HR',
'content' => '<p>'.gen_random_section_text(30,100).'</p>',
'level' => 2,
);
$sections[] = array(
'title' => 'History',
'content' => '<p>'.gen_random_section_text().'</p>',
'level' => 0,
);
$sections[] = array(
'title' => 'History (1990-2000)',
'content' => '<p>'.gen_random_section_text().'</p>',
'level' => 1,
);
$sections[] = array(
'title' => 'History (2001-Present)',
'content' => '<p>'.gen_random_section_text().'</p>',
'level' => 1,
);
//Now we'll take our fake sections and add pages/content as needed.
foreach($sections as $section) {
$headertag = 'h1';
if(empty($section['level'])) {
//Both not set and value of 0 will evaluate true here.
//I'm adding new pages for any top-level section here, but you don't need to.
$pdf->addPage();
$level = 0;
} else {
//Any non-zero level header I'll give an h2.
$headertag = 'h2';
$level = $section['level'];
}
//We add a bookmark right before we start our output for the section copy.
$bookmark_style = $level > 0 ? 'I' : 'B'; //Make subheading italic.
$pdf->Bookmark($section['title'], $level, -1, '', $bookmark_style, $level_colors[$level], -1, '');
//See below for some notes on the Bookmark method.
//Then we output our content.
$pdf->WriteHTML("<{$headertag}>".htmlspecialchars($section['title'], ENT_COMPAT, 'UTF-8').
"</{$headertag}> {$section['content']}");
}
// add a new page for TOC
$pdf->addTOCPage();
// write the TOC title
$pdf->SetFont('times', 'B', 16);
//Writes my little "TOC Note"
$pdf->MultiCell(0, 0, 'My Table Of Content', 0, 'C', 0, 1, '', '', true, 0);
$pdf->Ln();
$pdf->SetFont('dejavusans', '', 12);
// add a simple Table Of Content at first page
// (check the example n. 59 for the HTML version)
$pdf->addTOC(1, 'courier', '.', 'INDEX', 'B', array(128,0,0));
// end of TOC page
$pdf->endTOCPage();
//Close and output PDF document
$pdf->Output('example_045.pdf', 'I');
For reference, the parameters for Bookmark are, at time of writing, here:
#param $txt (string) Bookmark description.
#param $level (int) Bookmark level (minimum value is 0).
#param $y (float) Y position in user units of the bookmark on the selected page (default = -1 = current position; 0 = page start;).
#param $page (int|string) Target page number (leave empty for current page). If you prefix a page number with the * character, then this page will not be changed when adding/deleting/moving pages.
#param $style (string) Font style: B = Bold, I = Italic, BI = Bold + Italic.
#param $color (array) RGB color array (values from 0 to 255).
#param $x (float) X position in user units of the bookmark on the selected page (default = -1 = current position;).
#param $link (mixed) URL, or numerical link ID, or named destination (# character followed by the destination name), or embedded file (* character followed by the file name).
I am working with phpWord and bringing changes to the header/footer content gives me a real hard time. What I am trying is to have header content arranged in a table. The table is created through the code I write. But the styles I try to apply to the table placed in a header does not take effect.
Following is a part of my code in which I may be making a mistake.
$phpWordObj = new PhpWord();
$section = $phpWordObj->addSection();
$styleTable = array('borderSize' => 18, 'borderColor' => '006699');
$phpWordObj->addTableStyle('My Custom Style', $styleTable);
//ADD HEADER TO DOCUMENT
$header = $section->addHeader();
$header->firstPage();
$table = $header->addTable();
$table->addRow();
//logo
$table->addCell(2000)->addImage(
'../vendor/phpoffice/phpword/samples/resources/PhpWord.png',
array('width' => 80, 'height' => 80, 'align' => 'left')
); //logo
$cell = $table->addCell(7000);
$textrun = $cell->addTextRun();
$textrun->addText(htmlspecialchars('Custom Name goes here...'));
$headerGen = $section->addHeader();
$tableGenHeader = $headerGen->addTable();
$tableGenHeader->addRow();
//logo
$tableGenHeader->addCell(2000)->addImage(
'../vendor/phpoffice/phpword/samples/resources/PhpWord.png',
array('width' => 80, 'height' => 80, 'align' => 'left')
);
$cellGenHeader = $tableGenHeader->addCell(7000);
$textrunGenHeader = $cellGenHeader->addTextRun();
$textrunGenHeader->addText(htmlspecialchars('Custom Name goes here...'));
All I want is borders to appear so that the header contents can be differentiated from each other.
Thanks!
The $phpWordObj->addTableStyle(...) adds a new table style that you need to reference in the table addition (i.e. it is not a global definition). Adding the style name as a parameter to your addTable calls should do the trick:
$table = $header->addTable('My Custom Style');