profile
viewpoint
If you are wondering where the data of this site comes from, please visit https://api.github.com/users/oleibman/events. GitMemory does not store any data, but only uses NGINX to cache data for a period of time. The idea behind GitMemory is simply to give users a better reading experience.

PHPOffice/PhpSpreadsheet 10002

A pure PHP library for reading and writing spreadsheet files

oleibman/Common 0

Shared components between all PHPOffice projects

oleibman/PHPExcel 0

ARCHIVED

oleibman/PhpSpreadsheet 0

A pure PHP library for reading and writing spreadsheet files

oleibman/PHPWord 0

A pure PHP library for reading and writing word processing documents

issue openedPHPOffice/PhpSpreadsheet

PPMT() function should not asserts that rate is a positive number

This is:

- [x] a bug report

What is the expected behavior?

In an native excel, the =PPMT (rate, per, nper, pv, [fv], [type]) function allows rate parameter to be a negative value.

Screenshot 2021-06-15 at 18 34 17

What is the current behavior?

The changes added in this commit/line now trigger error when calculating value of the PPMT function when negative rate value is given to it.

I have to admit that I'm not an expert on what the PPMT function does and how it is meant to be used but we have a lot of excel files from experts in the financial industry and they seem to use a negative rate value in this function which now causes our app to crash.

My proposed solution is to simply remove that one line of validation which will make PHPOffice/PhpSpreadsheet behave consistently with native excel.

Which versions of PhpSpreadsheet and PHP are affected?

Effected PhpSpreadsheet version: 1.18.0 and higher

created time in 2 hours

issue commentPHPOffice/PhpSpreadsheet

restore explicit list of changes to PHPExcel migration document

Thanks you so much @nschulzke for highlighting this issue. I ran into a similar problem as I was trying to migrate my code using rector. I had to manually review each line of code which was calling the function setCellValueByColumnAndRow() and increment all my indices +1 in order to make it work.

It would be great to specify in the API doc that indices in now start from 1 and not from 0.

bradbulger

comment created time in 3 hours

pull request commentPHPOffice/PhpSpreadsheet

Xlsx Reader Better Namespace Handling Phase 1

Don't go ahead! Those merge conflicts need resolution first; I've tried manually resolving them once already, and ended up with a slew of errors. I'll have another go later, and try to identify what the actual problems are with the merge

oleibman

comment created time in 5 hours

issue commentPHPOffice/PhpSpreadsheet

Phpspreadsheet Charts don't work when adding multiple sheets - demo code works fine one worksheet, blank for 2+

Looking at the chart1.xml (after unzipping the sheet) the main items missing completely are the DataSeriesLables. For example

<c:f>Worksheet!$B$3</c:f><c:strCache><c:ptCount val="1"/><c:pt idx="0"><c:v>Course Minutes</c:v></c:pt></c:strCache></c:strRef></c:tx><c:invertIfNegative val="0"/><c:cat><c:strRef>

The $xAxisTickValues are there but missing their values

The rest of the .xml looks ok although series data xml ends with <c:tx><c:strRef> on the good chart but <c:invertIfNegative val="0"/><c:val><c:numRef> when the spreadsheet has multiple worksheets which may or may not be relevant.

brianlmerritt

comment created time in 7 hours

pull request commentPHPOffice/PhpSpreadsheet

Fix for #2149 / Read data validations for drop down list in another sheet.

Thank you for this contribution: it may be reworked a bit as we work with the handling of namespaces in Xlsx files

otargetj2s

comment created time in 7 hours

push eventPHPOffice/PhpSpreadsheet

Olivier TARGET

commit sha 803737a893ef6e8b2b46050577e83453e774e223

Fix for #2149 / Read data validations for drop down list in another sheet. (#2150) * Read data validations for drop down list in another sheet. * Add function testLoadXlsxDataValidationOfAnotherSheet() in class tests/PhpSpreadsheetTests/Reader/XlsxTest.php for unit test. * Add sample xlsx for unit tests. * Modifiy call function isset() for warnings. * Additional assertions to ensure that the worksheet has been read correctly for DataValidation that references a list on a different worksheet * This should resolve the phpstan issues Co-authored-by: Mark Baker <mark@lange.demon.co.uk>

view details

push time in 7 hours

PR merged PHPOffice/PhpSpreadsheet

Fix for #2149 / Read data validations for drop down list in another sheet.

This is:

- [x] a bugfix
- [ ] a new feature

Checklist:

  • [x] Changes are covered by unit tests
  • [x] Code style is respected
  • [x] Commit message explains why the change is made (see https://github.com/erlang/otp/wiki/Writing-good-commit-messages)
  • [ ] CHANGELOG.md contains a short summary of the change
  • [ ] Documentation is updated as necessary

Why this change is needed?

This modification makes it possible to read the drop-down lists linked to other sheets. See issue #2149

+42 -0

5 comments

3 changed files

otargetj2s

pr closed time in 7 hours

pull request commentPHPOffice/PhpSpreadsheet

Fix for #2149 / Read data validations for drop down list in another sheet.

I've added some more assertions to verify that the list address is correctly loaded with the worksheet name, and resolved the phpstan issue

otargetj2s

comment created time in 8 hours

issue openedPHPOffice/PhpSpreadsheet

Phpspreadsheet Charts don't work when adding multiple sheets - demo code works fine one worksheet, blank for 2+

This is:

- [x] a bug report
- [ ] a feature request
- [ ] **not** a usage question (ask them on https://stackoverflow.com/questions/tagged/phpspreadsheet or https://gitter.im/PHPOffice/PhpSpreadsheet)

What is the expected behavior?

Creating charts with multiple worksheets should not be different from creating charts with just one worksheet

What is the current behavior?

I can create one or 2 charts happily so long as I stick to the first worksheet, but as soon as I add multiple worksheets the charts written are corrupted or just blank.

What are the steps to reproduce?

Please provide a Minimal, Complete, and Verifiable example of code that exhibits the issue without relying on an external Excel file or a web server:

If you run the code below with $stickToOneSheet set to true, the code runs fine.

There are several options for adding a worksheet and 2 (different?) $writers and none of them produce working charts if there is more than one worksheet.

<?php

require __DIR__ . '/vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\Chart\Chart;
use PhpOffice\PhpSpreadsheet\Chart\DataSeries;
use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues;
use PhpOffice\PhpSpreadsheet\Chart\Legend;
use PhpOffice\PhpSpreadsheet\Chart\PlotArea;
use PhpOffice\PhpSpreadsheet\Chart\Title;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;



$stickToOneSheet = true;
$useNewWriterFactory = false;
$cloneNewWorksheet = true; // Only relevant if multiple sheets
$multipleCharts = true;
$title = 'newworksheet';

$spreadsheet = new Spreadsheet();

if ($stickToOneSheet) {
    $worksheet = $spreadsheet->getActiveSheet();

} elseif ($cloneNewWorksheet) {
    $worksheet1 = $spreadsheet->getActiveSheet();
    $worksheet = clone $worksheet1;
    $worksheet->setTitle($title);
    $spreadsheet->addSheet($worksheet,1);
} elseif ($useNewWriterFactory) {

    $worksheet = new Worksheet($spreadsheet, $title);
    $spreadsheet->addSheet($worksheet,1);
} else {
    echo "Sorry, no idea what you want to test";
    die;
}


// Todo generate data in this format
$data = [  // Note this data need to be transposed
    ['Tutor Dashboard Report for someone@example.com'],
    [''],
    ['','Course Minutes','Quiz Minutes','Book Minutes','Other Minutes','Panopto Minutes','Total Minutes', 'Graded Activities', '# Vidoes Watched', '# Watched Completely', 'Quartile Rank'],
    ['Sep20',22,23,65,60,37,256,2,3,2,1],
    ['Oct20',18,39,47,68,38,256,2,3,2,1],
    ['Nov20',12,15,43,67,38,256,4,3,2,3],
    ['Dec20',4,1,154,0,21,256,2,3,2,1],
    ['Jan21',22,15,38,18,10,256,4,4,2,4],
    ['Feb21',18,39,47,68,38,256,2,3,2,1],
    ['Mar21',12,15,43,67,38,256,2,5,2,1],
    ['Apr21',4,1,154,14,21,256,2,1,1,1],
    ['May21',18,39,47,68,38,256,2,3,2,2],
];


$worksheet->fromArray($data);


$num_columns = count($data[2]);
$num_rows = count($data)-3;
echo "\n\nColumns: $num_columns, Rows: $num_rows\n\n";

// Set the Labels for each data series we want to plot
//     Datatype
//     Cell reference for data
//     Format Code
//     Number of datapoints in series
//     Data values
//     Data Marker
//Todo set start values to calculations
$dataSeriesLabels = [
    new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$3', null, 1), // Course
    new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$3', null, 1), // Quiz
    new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$3', null, 1), // Books
    new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$E$3', null, 1), // Other
    new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$F$3', null, 1), // Panopto
];
// Set the X-Axis Labels
//     Datatype
//     Cell reference for data
//     Format Code
//     Number of datapoints in series
//     Data values
//     Data Marker
$xAxisTickValues = [
    //Todo set values to calculations
    new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$4:$A$12', null, 4), // Q1 to Q4
];
// Set the Data values for each data series we want to plot
//     Datatype
//     Cell reference for data
//     Format Code
//     Number of datapoints in series
//     Data values
//     Data Marker
//Todo set start and end values to calculations
$dataSeriesValues = [
    new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$4:$B$12', null, 4),
    new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$4:$C$12', null, 4),
    new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$4:$D$12', null, 4),
    new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$E$4:$E$12', null, 4),
    new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$F$4:$F$12', null, 4),
];

// Build the dataseries
$series = new DataSeries(
    DataSeries::TYPE_BARCHART, // plotType
    DataSeries::GROUPING_STACKED, // plotGrouping
    range(0, count($dataSeriesValues) - 1), // plotOrder
    $dataSeriesLabels, // plotLabel
    $xAxisTickValues, // plotCategory
    $dataSeriesValues        // plotValues
);
// Set additional dataseries parameters
//     Make it a vertical column rather than a horizontal bar graph
$series->setPlotDirection(DataSeries::DIRECTION_COL);

// Set the series in the plot area
$plotArea = new PlotArea(null, [$series]);
// Set the chart legend
$legend = new Legend(Legend::POSITION_RIGHT, null, false);

$title = new Title('Tutor Dashboard - brmerritt@rvc.ac.uk'); // Todo add student email
$yAxisLabel = new Title('Learning Minutes');

// Create the chart
$chart = new Chart(
    'chart1', // name
    $title, // title
    $legend, // legend
    $plotArea, // plotArea
    true, // plotVisibleOnly
    DataSeries::EMPTY_AS_GAP, // displayBlanksAs
    null, // xAxisLabel
    $yAxisLabel  // yAxisLabel
);

// Set the position where the chart should appear in the worksheet
$chart->setTopLeftPosition('A'.($num_rows + 7));
$chart->setBottomRightPosition('M'.($num_rows + 22));

// Add the chart to the worksheet
$worksheet->addChart($chart);

if ($multipleCharts) {


    // OK, try adding another chart!
    $dataSeriesLabels2 = [
        //new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$G$3', null, 1), // Total Minutes - ignore!
        new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$H$3', null, 1), // Graded Activities
        new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$I$3', null, 1), // Videos Watched
        new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$J$3', null, 1), // Watched Completely
        new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$K$3', null, 1), // Quartile Ranking
    ];
    $xAxisTickValues2 = [
        //Todo set values to calculations
        new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$4:$A$12', null, 4), // Q1 to Q4
    ];

    //Todo set start and end values to calculations
    $dataSeriesValues2 = [
        new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$H$4:$H$12', null, 4),
        new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$I$4:$I$12', null, 4),
        new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$J$4:$J$12', null, 4),
        new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$K$4:$K$12', null, 4),
        //new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$F$4:$F$12', null, 4),
    ];

    // Build the dataseries
    $series2 = new DataSeries(
        DataSeries::TYPE_BARCHART, // plotType
        DataSeries::GROUPING_CLUSTERED, // plotGrouping
        range(0, count($dataSeriesValues2) - 1), // plotOrder
        $dataSeriesLabels2, // plotLabel
        $xAxisTickValues2, // plotCategory
        $dataSeriesValues2        // plotValues
    );
    // Set additional dataseries parameters
    //     Make it a vertical column rather than a horizontal bar graph
    $series2->setPlotDirection(DataSeries::DIRECTION_COL);

    // Set the series in the plot area
    $plotArea2 = new PlotArea(null, [$series2]);
    // Set the chart legend
    $legend2 = new Legend(Legend::POSITION_RIGHT, null, false);

    $title2 = new Title('Graded Activities, Videos Watched, and Quartile Ranking'); // Todo add student email
    $yAxisLabel2 = new Title('Number of Each');


    $chart2 = new Chart(
        'chart2', // name
        $title2, // title
        $legend2, // legend
        $plotArea2, // plotArea
        true, // plotVisibleOnly
        DataSeries::EMPTY_AS_GAP, // displayBlanksAs
        null, // xAxisLabel
        $yAxisLabel2  // yAxisLabel
    );
    // Set the position where the chart should appear in the worksheet
    $chart2->setTopLeftPosition('A' . ($num_rows + 29));
    $chart2->setBottomRightPosition('M' . ($num_rows + 44));

    // Add the chart to the worksheet
    $worksheet->addChart($chart2);
}

// Save Excel file

$filename = "test_col1_stacked_7.xlsx";
if ($useNewWriterFactory) {
    $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
} else {
    $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
}

$writer->setIncludeCharts(true);
$callStartTime = microtime(true);
$writer->save($filename);
return 0;

// add code that show the issue here...

$stickToOneSheet = false; // Change the code above and the charts will not have visible data or be corrupted.

Which versions of PhpSpreadsheet and PHP are affected?

PHP 7.4.12 Phpspreadsheet versions 1.16 and 1.18 Excel version 2105 build 14026...

created time in 8 hours

push eventPHPOffice/PhpSpreadsheet

oleibman

commit sha 1e74282259c325d575cf1afb453d490419b84ccc

Fix for Issue 2158 (AverageIf Calculation Problem) (#2160) * Improve Identification of Samples in Coverage Report The Phpunit coverage report currently contains bullet items like `PhpOffice\PhpSpreadsheetTests\Helper\SampleTest\testSample with data set "49"`. This extremely simple change takes advantage of Phpunit's ability to accept an array with keys which are either strings or integers, by using the sample filenames as the array keys rather than sequential but otherwise meaningless integers (e.g. `49` in the earlier cited item). The bullet item will now read `PhpOffice\PhpSpreadsheetTests\Helper\SampleTest\testSample with data set "Basic/38_Clone_worksheet.php"`. * Fix for Issue 2158 (AverageIf Calculation Problem) Issue #2158 reports an error calculating AverageIf because a function returns null rather than a string. There turn out to be several components to this problem: - The nominal fix to the problem is to add some null-to-nullstring coercion in DatabaseAbstract. - This fixes the error, but does not necessarily lead to the correct result because buildQuery treats values of null and null-string identically, whereas Excel does not. So change that to treat null-string as any other string. - But that doesn't lead to the correct result either. That's because Functions/ifCondition recognizes a null string, but then continues to (over-)process it until it returns the wrong result. Fix this problem in conjunction with the other two, and we finally get the correct result. A new unit test is added for AVERAGEIF, and new test cases are added for SUMIF. In each case, there are complementary tests for conditions of null and null-string, and the results agree with Excel. There may or may not be value in adding new tests to other functions, and I will be glad to do so for any functions which you care to identify, but no existing tests broke as a result of these changes.

view details

push time in 11 hours

PR merged PHPOffice/PhpSpreadsheet

Fix for Issue 2158 (AverageIf Calculation Problem)

This is:

- [x] a bugfix
- [ ] a new feature

Checklist:

  • [x] Changes are covered by unit tests
  • [x] Code style is respected
  • [x] Commit message explains why the change is made (see https://github.com/erlang/otp/wiki/Writing-good-commit-messages)
  • [ ] CHANGELOG.md contains a short summary of the change
  • [ ] Documentation is updated as necessary

Why this change is needed?

Issue #2158 reports an error calculating AverageIf because a function returns null rather than a string. There turn out to be several components to this problem:

  • The nominal fix to the problem is to add some null-to-nullstring coercion in DatabaseAbstract.
  • This fixes the error, but does not necessarily lead to the correct result because buildQuery treats values of null and null-string identically, whereas Excel does not. So change that to treat null-string as any other string.
  • But that doesn't lead to the correct result either. That's because Functions/ifCondition recognizes a null string, but then continues to (over-)process it until it returns the wrong result. Fix this problem in conjunction with the other two, and we finally get the correct result.

A new unit test is added for AVERAGEIF, and new test cases are added for SUMIF. In each case, there are complementary tests for conditions of null and null-string, and the results agree with Excel. There may or may not be value in adding new tests to other functions, and I will be glad to do so for any functions which you care to identify, but no existing tests broke as a result of these changes.

+63 -6

0 comment

5 changed files

oleibman

pr closed time in 11 hours

issue commentPHPOffice/PhpSpreadsheet

The filename is not recognised as an OLE file

Hello Mark, thank you for the detailed explanation. I was wondering about the CDATA tags but makes sense they should be used in this case.

It might be possible to add a stream filter to the Xml Reader that would convert the HTML Entities to valid XML Entities before it's passed to simplexml_load_string(), but I'd have to investigate that further

Let me know if there is anything I can do to help.

roland-d

comment created time in 12 hours

push eventPHPOffice/PhpSpreadsheet

oleibman

commit sha 4f06d8424805e1ef00985128c522f3b2c1f017ca

TextData - Minor Changes, Test Coverage (#2151) * PHP8.1 Deprecation Passing Null to String Function For each of the files in this PR, one or more statements can pass a null to string functions like strlower. This is deprecated in PHP8.1, and, when deprecated messages are enabled, causes many tests to error out. In every case, use coercion to pass null string rather than null. * TextData - Minor Changes, Test Coverage Per agreement on a previous push, I looked into standardizing the initialization of the TextData functions (like Engineering and MathTrig), with particular regard for avoiding multiple later null coercions. This simplifies the code quite a bit. This PR also increases coverage to 100% for all TextData modules. All entries in Phpstan baseline for non-deprecated TEXTDATA functions are removed. There were some minor bugfixes. Whereas Excel (and Gnumeric) treat booleans when supplied as strings as 'TRUE' or 'FALSE', ODS treats them as '1' or '0'. Unlike Excel, ODS generally does not allow bool for int arguments; it does, however, allow them for FIND and SEARCH. ODS allows boolean for into for SUBSTITUTE even though Excel doesn't. ODS allows bool for string for NUMBERVALUE and VALUE even though Excel doesn't. ODS accepts 0 as an argument for CHAR; Excel doesn't. Most of this seems like random decisions on the part of the developers; I've done my best to follow the products in each case. There is a new test member devoted to ODS tests. Gnumeric has an anomaly vis-a-vis the others - if length is supplied to LEFT/MID/RIGHT as null, Gnumeric treats it as 0 rather than 1. All tests now take place in the context of a spreadsheet ... Except for RETURNSTRING, which is not the implementation of an Excel function, and is referred to in the rest of PhpSpreadsheet only in the unit tests for itself. It should probably be deprecated, but that is not part of this PR, just in case there is some reason for it that I couldn't discern. I have tried to make the first line of each doc block identify the Excel function name rather than its name in PhpSpreadsheet. I think it makes things more comprehensible. Some tests call Settings::setLocale, but there was no Settings::getLocale. At the end of the tests which do it, they invoke setLocale('EN-US'), which, in a practical sense, is sufficient. However, in theory it would be better for them to get the current locale before changing it, then changing it back to the original when the time came. I have added getLocale and made the appropriate testing change. The CHAR function took an interesting turn. One can set the value of a cell to, say, CHAR(2), the ASCII/UTF-8 representation of a control character, which is not legal in certain contexts. The only Reader/Writer that could handle this without problems is Xls, which deals with binary data all the time. However, if you tried to write it to Xlsx, Excel would not be able to open the resulting file because of what it considers an illegal character. I changed the Xlsx writer to escape such characters when writing the value of a string function. I did not make any other changes to the Xlsx writer - it seems to me that setting a cell to CHAR(2) is legitimate, but setting it to say `"\x02"` seems less likely to be legitimate, so the latter will still fail (although `="\x02"` should work). The Xlsx reader already supports the escape mechanism that I added to the writer. CHAR control character and Ods - not supported by either Reader or Writer. I did not attempt to add this now. There is lots still missing from ODS, and this item just can't be a high priority amongst all of those. CHAR control character and Csv - it is supported by reader and writer if the file has a csv extension. However, trying to guess the mime type without an extension - the control character makes mime_get_type guess application/octet-stream, and PhpSpreadsheet therefore thinks that Csv can't read it. CHAR control character and Html. Actual use of the control character in the file is subject to the same problems as Xml (i.e. Xlsx and Ods). It wasn't terribly difficult to get the Html Writer to change `"\x02"` to "`&#2;`". I believe that this is technically legal; however, DOMDocument.loadHTML rejects it as an illegal entity, and I am not convinced that it is wrong to do so, so I haven't changed the Html writer. * Scrutinizer Correct 3 minor errors.

view details

push time in 12 hours

PR merged PHPOffice/PhpSpreadsheet

TextData - Minor Changes, Test Coverage

This is:

- [x] a bugfix (minor)
- [ ] a new feature
- [x] code cleanup

Checklist:

  • [x] Changes are covered by unit tests
  • [x] Code style is respected
  • [x] Commit message explains why the change is made (see https://github.com/erlang/otp/wiki/Writing-good-commit-messages)
  • [ ] CHANGELOG.md contains a short summary of the change
  • [ ] Documentation is updated as necessary

Why this change is needed?

Per agreement on a previous push, I looked into standardizing the initialization of the TextData functions (like Engineering and MathTrig), with particular regard for avoiding multiple later null coercions. This simplifies the code quite a bit. This PR also increases coverage to 100% for all TextData modules. All entries in Phpstan baseline for non-deprecated TEXTDATA functions are removed. There were some minor bugfixes.

Whereas Excel (and Gnumeric) treat booleans when supplied as strings as 'TRUE' or 'FALSE', ODS treats them as '1' or '0'. Unlike Excel, ODS generally does not allow bool for int arguments; it does, however, allow them for FIND and SEARCH. ODS allows boolean for into for SUBSTITUTE even though Excel doesn't. ODS allows bool for string for NUMBERVALUE and VALUE even though Excel doesn't. ODS accepts 0 as an argument for CHAR; Excel doesn't. Most of this seems like random decisions on the part of the developers; I've done my best to follow the products in each case. There is a new test member devoted to ODS tests.

Gnumeric has an anomaly vis-a-vis the others - if length is supplied to LEFT/MID/RIGHT as null, Gnumeric treats it as 0 rather than 1.

All tests now take place in the context of a spreadsheet ...

Except for RETURNSTRING, which is not the implementation of an Excel function, and is referred to in the rest of PhpSpreadsheet only in the unit tests for itself. It should probably be deprecated, but that is not part of this PR, just in case there is some reason for it that I couldn't discern.

I have tried to make the first line of each doc block identify the Excel function name rather than its name in PhpSpreadsheet. I think it makes things more comprehensible.

Some tests call Settings::setLocale, but there was no Settings::getLocale. At the end of the tests which do it, they invoke setLocale('EN-US'), which, in a practical sense, is sufficient. However, in theory it would be better for them to get the current locale before changing it, then changing it back to the original when the time came. I have added getLocale and made the appropriate testing change.

The CHAR function took an interesting turn. One can set the value of a cell to, say, CHAR(2), the ASCII/UTF-8 representation of a control character, which is not legal in certain contexts. The only Reader/Writer that could handle this without problems is Xls, which deals with binary data all the time. However, if you tried to write it to Xlsx, Excel would not be able to open the resulting file because of what it considers an illegal character. I changed the Xlsx writer to escape such characters when writing the value of a string function. I did not make any other changes to the Xlsx writer - it seems to me that setting a cell to CHAR(2) is legitimate, but setting it to say "\x02" seems less likely to be legitimate, so the latter will still fail (although ="\x02" should work). The Xlsx reader already supports the escape mechanism that I added to the writer.

CHAR control character and Ods - not supported by either Reader or Writer. I did not attempt to add this now. There is lots still missing from ODS, and this item just can't be a high priority amongst all of those.

CHAR control character and Csv - it is supported by reader and writer if the file has a csv extension. However, trying to guess the mime type without an extension - the control character makes mime_get_type guess application/octet-stream, and PhpSpreadsheet therefore thinks that Csv can't read it.

CHAR control character and Html. Actual use of the control character in the file is subject to the same problems as Xml (i.e. Xlsx and Ods). It wasn't terribly difficult to get the Html Writer to change "\x02" to "&#2;". I believe that this is technically legal; however, DOMDocument.loadHTML rejects it as an illegal entity, and I am not convinced that it is wrong to do so, so I haven't changed the Html writer.

+1425 -559

0 comment

66 changed files

oleibman

pr closed time in 12 hours

issue commentPHPOffice/PhpSpreadsheet

Miss Dynamic Tables

I just started work on the absolute basics of Pivot Tables for the Xlsx Reader/Writer two weeks ago... at the moment, I have some very simplistic code that just allows the pivot table to be read and written, without any form of editing or access to the data, just so that it won't get lost in a read/write; but that doesn't handle pivot tables that have any form of customisation (even something as basic as a custom style will trigger errors on the save) It's likely to take several months of work to get something robust enough to merge, and that depends how much time I get to work on it over the Summer.

ovgp

comment created time in a day

issue commentPHPOffice/PhpSpreadsheet

Miss Dynamic Tables

Correct... none of the Readers support dynamic tables like pivot tables. That is something we are currently investigating

Thanks in advance. I think it's a very important function because I need to integrate with some softwares, for example, Microsoft Dynamics NAV (from Rapid Start).

I need to use https://products.aspose.app/cells/editor to keep Dynamic Tables.

Are you working on that? It will take long time?

Thanks in advance.

ovgp

comment created time in a day

issue commentPHPOffice/PhpSpreadsheet

Miss Dynamic Tables

Correct... none of the Readers support dynamic tables like pivot tables. That is something we are currently investigating

ovgp

comment created time in a day

issue commentPHPOffice/PhpSpreadsheet

The filename is not recognised as an OLE file

The Xls Reader will not read the file, because it isn't an xls file (Just giving a file an extension of .xls doesn't make it an ls file), it isn't BIFF-format, but Xml as you note. This is why we provide the IOFactory's identify() method, to determine the correct Reader to use because files are commonly misnamed with the wrong extension for their actual file type. The identify() method looks at the basic content and structure of the file to determine what it really is, not simply what the extension claims it is. The load() method uses identify() to determine which Reader should be used,

The Xml Reader will not load it however, because it isn't valid Xml. Entities like &iota; as HTML Entities, but aren't Xml Entities. It would only be valid if those entities were actually defined in the file itself, or were used within CDATA blocks. And the file itself is UTF-8, so there is no need to use HTML Entities in the file at all. In practise, we disallow the definition of entities within the Xml that we load, because allowing Entity definition also allows XXE/XEE attacks. Spreadsheet programs like Excel are clearly more forgiving, and will read this and convert the invalid HTML Entities. It might be possible to add a stream filter to the Xml Reader that would convert the HTML Entities to valid XML Entities before it's passed to simplexml_load_string(), but I'd have to investigate that further

roland-d

comment created time in a day

issue openedPHPOffice/PhpSpreadsheet

Miss Dynamic Tables

This is:

- [ ] a bug report
- [ ] a feature request
- [ ] **not** a usage question (ask them on https://stackoverflow.com/questions/tagged/phpspreadsheet or https://gitter.im/PHPOffice/PhpSpreadsheet)

What is the expected behavior?

Open the excel file (.xlsx) with dynamic tables and save the same file with dynamic tables

What is the current behavior?

The spreadsheet opens the excel file and saves the file without dynamic tables. Only plain text.

What are the steps to reproduce?

Use reader fuction to open the file Force to readonly Define a worksheet Use writer function to save the file

Please provide a Minimal, Complete, and Verifiable example of code that exhibits the issue without relying on an external Excel file or a web server:

<?php

require __DIR__ . '/vendor/autoload.php';

// Create new Spreadsheet object
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;

// add code that show the issue here...

$inputFileName = 'template-sample.xlsx';

$inputFileType = IOFactory::identify($inputFileName); $reader = IOFactory::createReader($inputFileType); $reader->setReadDataOnly(true); $spreadsheet = $reader->load($inputFileName);

$spreadsheet->setActiveSheetIndex(1);

$writer = IOFactory::createWriter($spreadsheet, "Xlsx"); $writer->save("template-test.xlsx");

Which versions of PhpSpreadsheet and PHP are affected?

1.18.0

created time in a day

issue commentPHPOffice/PhpSpreadsheet

HLookup::hLookupSearch(..) sends wrong arguments to LookupBase::checkMatch(..).

This is still and issue for us so I created a test excel sheet to demonstrate the problem.

Running this code:

$spreadsheet = IOFactory::load('./hlookup-test.xlsx');
$sheet = $spreadsheet->getSheet(0);
$cellVal = $sheet->getCell('H8')->getCalculatedValue();

On this excel spreadsheet: hlookup-test.xlsx

Screenshot 2021-06-14 at 16 49 22

Results in:

TypeError {#3754
  #message: "Argument 4 passed to PhpOffice\PhpSpreadsheet\Calculation\LookupRef\LookupBase::checkMatch() must be of the type int, string given, called in xxx/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/HLookup.php on line 74"
  #code: 0
  #file: "./vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/LookupBase.php"
  #line: 25
  trace: {
    ./vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/LookupBase.php:25 { …}
    ./vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/HLookup.php:74 { …}
    ./vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef/HLookup.php:45 { …}
    PhpOffice\PhpSpreadsheet\Calculation\LookupRef\HLookup::lookup() {}
    ./vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Calculation.php:4846 { …}
    ./vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Calculation.php:3539 { …}
    ./vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Calculation.php:3332 { …}
    ./vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Cell.php:259 { …}
    ./src/MyNamespace/Command/TestExcel.php:30 {
      MyNamespace\Command\TestExcel->execute(InputInterface $input, OutputInterface $output): void
      › $sheet = $spreadsheet->getSheet(0);
      › $cellVal = $sheet->getCell('H8')->getCalculatedValue();
      › 
    }

ping @MarkBaker let me know if I should provide any more information ;-)

majermi4

comment created time in a day

issue openedPHPOffice/PhpSpreadsheet

Return Value Error - DatabaseAbstruct::buildQuery() return null but must be string

This is:

- [x] a bug report

What is the expected behavior?

DatabaseAbstruct::buildQuery() return string

What is the current behavior?

DatabaseAbstruct::buildQuery() return null but it must be string, throwed Return Value Error

What are the steps to reproduce?

An error occurs when I try to export a spreadsheet with the following formula,

=AVERAGEIF(A:A, "", B:B)

when a blank cell is specified in the search condition.

<?php

require __DIR__ . '/vendor/autoload.php';

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();

// Create new Spreadsheet object
$spreadSheet = $reader->load('example.xlsx');

$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadSheet);
$writer->save('php://output'); // anywhere

// add code that show the issue here...

Which versions of PhpSpreadsheet and PHP are affected?

created time in a day

issue openedPHPOffice/PhpSpreadsheet

The filename is not recognised as an OLE file

This is:

- [x] a bug report

Not even sure if this is a bug report or a feature request as I could not find if this type of XLS file is supported.

What is the expected behavior?

PhpSpreadsheet to read the file as I can open it just fine in OpenOffice.

What is the current behavior?

Trying to read the file I get the error The filename products.xls is not recognised as an OLE file trying to read it as Xls. Trying to read it as Xml because the content is just XML, generates a lot of PHP warnings:

HP Warning:  simplexml_load_string(): Entity: line 1261: parser error : Entity 'iota' not defined in /vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml.php on line 120
PHP Warning:  simplexml_load_string(): &Omicron;&iota; &Kappa;ά&nu;&phi;&iota;&lambda;&nu;&tau; &kappa;&alpha;&iota; & in /vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml.php on line 120
PHP Warning:  simplexml_load_string():                                         ^ in /vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml.php on line 120
PHP Warning:  simplexml_load_string(): Entity: line 1261: parser error : Detected an entity reference loop in /vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml.php on line 120
PHP Warning:  simplexml_load_string(): &Omicron;&iota; &Kappa;ά&nu;&phi;&iota;&lambda;&nu;&tau; &kappa;&alpha;&iota; & in /vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml.php on line 120
PHP Warning:  simplexml_load_string():                                         ^ in /vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml.php on line 120

What are the steps to reproduce?

The file used in this example: ProductsAPI-14-06-2021.xls

Please provide a Minimal, Complete, and Verifiable example of code that exhibits the issue without relying on an external Excel file or a web server:

This is trying to read it as XLS:

<?php

use PhpOffice\PhpSpreadsheet\IOFactory;

require __DIR__ . '/vendor/autoload.php';
$reader        = IOFactory::createReader('Xls');
$reader->setLoadAllSheets();
$spreadsheet     = $reader->load('products.xls');

This is trying to read it as XML:

<?php

use PhpOffice\PhpSpreadsheet\IOFactory;

require __DIR__ . '/vendor/autoload.php';
$reader        = IOFactory::createReader('Xml');
$reader->setLoadAllSheets();
$spreadsheet     = $reader->load('products.xls');

I have also tried it with this code:

<?php

use PhpOffice\PhpSpreadsheet\IOFactory;

require __DIR__ . '/vendor/autoload.php';

$excel = IOFactory::load('products.xls');

That results in the same output as trying to read it as an XML file above.

Which versions of PhpSpreadsheet and PHP are affected?

1.18.0

created time in a day

pull request commentPHPOffice/PhpSpreadsheet

Xlsx Reader Better Namespace Handling Phase 1

I'll take a look at lunchtime (CEST) but most of the merge conflicts seem to resolve around reading the date properties from the document, and a big conflict in XlsxTest.php

oleibman

comment created time in a day

push eventPHPOffice/PhpSpreadsheet

MarkBaker

commit sha 66cd68daeab53e921c65d77db4629a76cc233133

Update Change log

view details

push time in 2 days

push eventPHPOffice/PhpSpreadsheet

Mark Baker

commit sha 74b02fb31c9b3b72f7e1785ccfa19937bc1bea9f

Fix for the BIFF-8 Xls colour mappings in the Reader (#2156) * Fix for the BIFF-8 Xls colour mappings in the Reader * Unit test for reading colours, writing hen rereading and ensuring that the RGB values have not changed

view details

push time in 2 days

PR merged PHPOffice/PhpSpreadsheet

Fix for the BIFF-8 Xls colour mappings in the Reader

This is:

- [X] a bugfix
- [ ] a new feature

Checklist:

  • [ ] Changes are covered by unit tests
  • [X] Code style is respected
  • [X] Commit message explains why the change is made (see https://github.com/erlang/otp/wiki/Writing-good-commit-messages)
  • [ ] CHANGELOG.md contains a short summary of the change
  • [ ] Documentation is updated as necessary

Why this change is needed?

Resolve BIFF-8 colour map for the Xls reader. This should fix Issue #2147

+98 -56

0 comment

3 changed files

MarkBaker

pr closed time in 2 days

issue closedPHPOffice/PhpSpreadsheet

Changing grey background to black in Excel template

This is:

- [x] a bug report
- [ ] a feature request
- [ ] **not** a usage question (ask them on https://stackoverflow.com/questions/tagged/phpspreadsheet or https://gitter.im/PHPOffice/PhpSpreadsheet)

What is the expected behavior?

Not change the cell background color

What is the current behavior?

Grey background cells are changing to black

What are the steps to reproduce?

Create spreadsheet with grey background cells Use IOFactory::load to load the spreadsheet Use the Xls writer to write a new spreadsheet

Please provide a Minimal, Complete, and Verifiable example of code that exhibits the issue without relying on an external Excel file or a web server:

<?php

require __DIR__ . '/vendor/autoload.php';

$spreadsheet = IOFactory::load('input.xls');

$writer = new Xls($spreadsheet);
	header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
	header('Content-Disposition: attachment; filename="output.xls"');
	$writer->save('php://output');

Which versions of PhpSpreadsheet and PHP are affected?

Works fine in 1.16.0. I noticed it broke in 1.18.0. Didn't test 1.17.0. I did look closer and 1.16.0 has a different shade of grey than what is originally there, but it's not doing what the latest version is doing which turns it to black.

closed time in 2 days

keithslater

push eventPHPOffice/PhpSpreadsheet

MarkBaker

commit sha 716124ca6012e0642f6d768c0a5009c3fc4e3c07

Unit test for reading colours, writing hen rereading and ensuring that the RGB values have not changed

view details

push time in 2 days

PR opened PHPOffice/PhpSpreadsheet

Fix for the BIFF-8 Xls colour mappings in the Reader

This is:

- [X] a bugfix
- [ ] a new feature

Checklist:

  • [ ] Changes are covered by unit tests
  • [X] Code style is respected
  • [X] Commit message explains why the change is made (see https://github.com/erlang/otp/wiki/Writing-good-commit-messages)
  • [ ] CHANGELOG.md contains a short summary of the change
  • [ ] Documentation is updated as necessary

Why this change is needed?

Resolve BIFF-8 colour map for the Xls reader

+56 -56

0 comment

1 changed file

pr created time in 3 days

create barnchPHPOffice/PhpSpreadsheet

branch : Xls-Colour-Mappings

created branch time in 3 days