spout
spout copied to clipboard
Enable est column width calculation
This is a first step to resolving https://github.com/box/spout/issues/129
This approach primarily computes the width size by using an estimate created
After the PR, the library may be used as follows (sample outputs are attached below):
<?php
use Box\Spout\Writer\Common\Creator\WriterEntityFactory;
use Box\Spout\Common\Type;
require __DIR__ . '/vendor/autoload.php';
function generateRows()
{
$data = [];
$headers = [];
for($i=0;$i<10;$i++) {
$headers[] = "COL-".generateRandomString(5);
}
$data = [
$headers
];
for($i=0; $i< 10; $i++) {
$row = [];
$rand = mt_rand(1, 30);
foreach ($headers as $header) {
$randLen = mt_rand(1, $rand);
$row[] = generateRandomString($randLen);
}
$data[] = $row;
}
return $data;
}
function generateRandomString($length = 10) {
$characters = 'aaaaeeeeiiiiiiiioooouuuubcdefghijklmnopqrstuvwxyz';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
$data = generateRows();
$writer = WriterEntityFactory::createWriter(Type::ODS);
$writer->setWidthCalculation(1);
$writer->openToFile('spouter.ods');
foreach ($data as $row) {
$writer->addRow(WriterEntityFactory::createRowFromArray($row));
}
$writer->close();
?>
@adrilo I noticed two tests are failing and it seems the test has an error... The two particular resource files involved are generated from a unix environment instead of the current environment.. I think those two files should be dynamically generated to ensure they are compatible with the particular environment..
Meanwhile I've attached further examples of using fixed width style calculation below..
<?php
use Box\Spout\Common\Type;
use Box\Spout\Writer\Common\Creator\Style\StyleBuilder;
use Box\Spout\Writer\Common\Creator\WriterEntityFactory;
require __DIR__ . '/vendor/autoload.php';
function generateRows()
{
$data = [];
$headers = [];
for($i=0;$i<10;$i++) {
$n = $i+1;
$headers[] = "COL-$n";
}
$data = [
$headers
];
for($i=0; $i< 10; $i++) {
$row = [];
$rand = mt_rand(1, 30);
foreach ($headers as $header) {
$randLen = mt_rand(1, $rand);
$row[] = generateRandomString($randLen);
}
$data[] = $row;
}
return $data;
}
function generateRandomString($length = 10) {
$characters = 'aaaaeeeeiiiiiiiioooouuuubcdefghijklmnopqrstuvwxyz';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
$data = generateRows();
$defaultStyle = (new StyleBuilder())
->setFontSize(36)
->build();
$boldtyle = (new StyleBuilder())
->setFontSize(42)
->setFontBold()
->build();
//$writer = WriterEntityFactory::createWriter(Type::ODS);
$writer = WriterEntityFactory::createWriter(Type::XLSX);
$writer->setWidthCalculation(2)->setDefaultRowStyle($defaultStyle)->openToFile('spoutw.xlsx');
//$writer->openToFile('spouter.xlsx');
foreach ($data as $i => $row) {
if ($i == 0) {
$writer->addRow(WriterEntityFactory::createRowFromArray($row, $boldtyle));
} else {
$writer->addRow(WriterEntityFactory::createRowFromArray($row));
}
}
$writer->close();
Hi, instead of overwriting dummy portion of the end file, just like ODS already did it with https://github.com/openspout/openspout/pull/45 now also XLSX writes the rows in a temporary file and only after that it writes all the remaining data, thanks to the speed of stream_copy_to_stream
.
So now column with, alongside auto-sizing, could be easily supported and already achievable by user code without affecting performances :rocket: