phpword table column reverse - php

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');

Related

PhpWord multi-colum layout issue

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!

Codeigniter with PHPspreadsheet how to put a condition if a data in database is empty the cell column will turn into red

Hi good day everyone who had an idea on how to make my PO status column cell will be red if there is no data yet had been inserted to the database. I am using phpspreadsheet in code igniter framework.
This is my spreadsheet code witch I want it if there is no PO STATUS yet the color will be seen in my column status is red.
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', 'Control Number');
$sheet->setCellValue('B1', 'Requesting Unit');
$sheet->setCellValue('C1', 'Project Details');
$sheet->setCellValue('D1', 'PO STATUS');
this is $data is the model where the sql query will fetch and how i fetch my data into the database.
$data = $this->m->statuswaived();
$slno = 1;
$start = 2;
foreach($data as $d){
$sheet->setCellValue('A'.$start, $d->control_number);
$sheet->setCellValue('B'.$start, $d->requesting_unit);
$sheet->setCellValue('C'.$start, $d->project_details);
$sheet->setCellValue('D'.$start, $d->po_status);
$start = $start+1;
$slno = $slno+1;
}
this code is for putting the border in my excel
$styleThinBlackBorderOutline = [
'borders' => [
'allBorders' => [
'borderStyle' => Border::BORDER_THIN,
'color' => ['argb' => 'FF000000'],
],
],
];
this code is use for bolding a cell column and alignment and fontsize that i set.
//Font BOLD
$sheet->getStyle('A1:D1')->getFont()->setBold(true);
$sheet->getStyle('A1:D1')->applyFromArray($styleThinBlackBorderOutline);
//Alignment
//fONT SIZE
// $sheet->getStyle('A1:D1')->getFont()->setSize(12);
$sheet->getStyle('A1:D1')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
This code is for setting the with of the cell column.
$sheet->getColumnDimension('A')->setWidth(30);
$sheet->getColumnDimension('B')->setWidth(30);
$sheet->getColumnDimension('C')->setWidth(30);
$sheet->getColumnDimension('D')->setWidth(30);

Laravel / Eloquent - Column name as variable

Eloquent offers a handy way of passing stuff to the database
$table_name = new TableName;
$table_name->column_name = "some data";
$table_name->save();
I've got quite a lot of data from a form that needs to be validated, so I was wondering if it was possible to replace the column name with a variable, so I can put it in some loop, and get the names and data from arrays.
$table_name->$columns[$i] = $data[$i];
(though I suppose not written in that way)
Update
In the end I've gone with the following:
$table_name = new TableName;
$nameArray=[
1 => 'form-name-1',
...
];
$columnArray=[
1 => 'column_name_1',
...
];
for($i=1;$i<=count($nameArray);$i++){
if(logic logic logic) $table_name->{$columnArray[$i]} = $_POST[$nameArray[$i]];
else $table_name->{$columnArray[$i]} = NULL;
}
$table_name->save();
You can do one these:
1) Create with values
$table_name = new TableName([
"column_name" => "column_value"
]);
2) Fill
$table_name = new TableName();
$table_name->fill([
"column_name" => "column_value"
]);
3) The way you suggested originally:
$valuesMap = [
"column_name" => "column_value"
];
$table_name = new TableName();
foreach ($valuesMap as $column => $value) {
$table_name->{$column} = $value; //The {} are optional in this case
}
Note that to do 1 or 2 all fields you put in the array must be fillable and not guarded.
You can use it like an associative array:
$table_name['column_name']
$column_name = 'column_name';
$table_name[$column_name];
Or you can loop their attributes
foreach($table_name->getAttributes() as $value => $key){
echo "The attr ".$key." has this value: ".$value;
}

Batch insert and arithmetic subtraction Yii 2

I have this function that doesn't batch insert to my database, I only used the batch insert function recently because back then I only used object inserts through for loops like this
$subject = ActiveCurriculum::find()
->select('scstock.*')
->joinWith('schead')
->where(['schead.TrNo' => $TrNo])
->one();
$activesubject = new ActiveSubject();
$activesubject->clientid = $clientid;
$activesubject->TrNo = $subject->TrNo;
$activesubject->LINE = $subject->LINE;
$activesubject->period = $subject->schead->period;
$activesubject->subjectcode = $subject->subjectcode;
$activesubject->schedday = $subject->schedday;
$activesubject->schedtime = $subject->schedtime;
//remember to use schead if the value is joined from another table.
$activesubject->section = $subject->schead->section;
$activesubject->roomcode = $subject->roomcode;
$activesubject->units = $subject->units;
$activesubject->save();
//reduces the slot of ccsubject by 1
$subject->slots = $subject->slots - 1;
//never forget the saving part
$subject->save();
I am not able to use this this time because I needed to insert an array of values so as I said I opted to this.
$subjects = ActiveCurriculum::find()
->select(['scstock.*', 'schead.*'])
->leftJoin('schead', 'schead.TrNo = scstock.TrNo')
->where(['sectiongroup' => $group])
->asArray()
->all();
// $activesubject = new ActiveSubject();
$bulkInsertArray = [];
foreach ($subjects as $values) {
$bulkInserArray[] = [
'clientid' => $clientid,
'TrNo' => $values['TrNo'],
'LINE' => $values['LINE'],
'period' => $values['period'],
'subjectcode' => $values['subjectcode'],
'schedday' => $values['schedday'],
'schedtime' => $values['schedtime'],
'section' => $values['section'],
'roomcode' => $values['roomcode'],
'units' => $values['units'],
];
if (count($bulkInsertArray) > 0) {
$columnNameArray = ['clientid', 'TrNo', 'LINE', 'period', 'subjectcode', 'schedday', 'schedtime', 'section', 'roomcode', 'units'];
// below line insert all your record and return number of rows inserted
$insertCount = Yii::$app->db->createCommand()
->batchInsert('subjectcontainer', $columnNameArray, $bulkInsertArray)
->execute();
}
}
But I am not able to
$subject->slots = $subject->slots - 1;
$subject->save();
like in the first one because of the arrays, can you tell me how to do this in my second code because I need to subtract the slots column by 1 every iteration of the for loop this time. Thank you.
You can perform subtraction using single query. Something like this:
$columnToUpdate = ['slots' => new \yii\db\Expression('[[slots]] - 1')];
$condition = ['sectiongroup' => $group];
ActiveCurriculum::updateAll( $columnToUpdate, $condition );
It will execute SQL:
UPDATE `active_curriculum` SET `slots`=`slots` - 1 WHERE `sectiongroup`=1234
You just need to make correct condition that correctly selects necessary rows. Alternatively, you can collect primary keys of records (IDs) when you prepare $bulkInserArray and use them for condition:
$condition = ['id' => $subjectIDsToUpdate];
This condition will build id IN (...) automatically.

phpWord - Tables with borders in headers/footers

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');

Categories