[PHP] save bytes uit response naar XLXS file

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • Red devil
  • Registratie: December 1999
  • Laatst online: 09:00
Hai tweakerts

Voor mijn site doe ik wat calculaties in Java die een Excel file opleveren. Deze gaan naar een OutputStream welke door mijn PHP site wordt opgepikt via een curl request. Nu wil ik deze resultaten naar een Excel file omzetten die dan door een gebruiker kan worden gedownload.

code:
1
2
3
4
5
6
7
8
9
10
11
12
$headers = [
                        'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
                        'Content-Description' => 'File Transfer',
                        'Content-Disposition' => "attachment; filename=matches.xlsx",
                        'Content-Transfer-Encoding' => 'binary',
                        'Pragma' => 'public',
                        'Expires' => '0',
                        'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
                        'Accept-Ranges' => 'bytes',
                    ];

                    return response($response, 200, $headers);


Ik krijg netjes de file, maar krijg hem niet geopend --> "We have found a problem with some content in 'matches (1).xlsx'. Do you want us to try to recover as much as we can? If you trust the source of this workbook, click Yes.

vervolgens

Excel cannot open the file 'matches (1).xlsx' because the file format or file extension is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file.

Als ik hem verander naar .xls krijg ik na het openen:

Afbeeldingslocatie: https://tweakers.net/i/1wTDefVJ5f1Yy2jOImg-jRhdfvI=/800x/filters:strip_exif()/f/image/ftuiPacLn7MVIBEwxwwBOMnV.png?f=fotoalbum_large

Als ik de file vanuit Java save naar een file, dan kan ik hem prima openen. Zijn er misschien nog wat PHP headers die ik moet aanpassen?

[ Voor 0% gewijzigd door Red devil op 20-02-2021 20:56 . Reden: een scherpe tweakert! ]

Alle reacties


Acties:
  • +1 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Je vertelt niet of response() een eigen ding is of uit een framework komt, maar het valt in ieder geval op dat het eerste element in de headers array een gehele header string is, terwijl de rest key=>value is. Komen alle headers daarmee wel goed over?

{signature}


Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
Je zou eens kunnen kijken of het xlsx-bestand een geldig zip-bestand is, om vervolgens de inhoud te vergelijken met de inhoud van een ander xlsx-bestand.

Acties:
  • 0 Henk 'm!

  • Red devil
  • Registratie: December 1999
  • Laatst online: 09:00
Voutloos schreef op zaterdag 20 februari 2021 @ 20:52:
Je vertelt niet of response() een eigen ding is of uit een framework komt, maar het valt in ieder geval op dat het eerste element in de headers array een gehele header string is, terwijl de rest key=>value is. Komen alle headers daarmee wel goed over?
Scherp! Gelijk gefixed naar

code:
1
'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',


helaas nog geen resultaat. Ik gebruik curl voor de response:

code:
1
2
3
4
5
$curl = curl_init();
#hier wat curl opties
$result = curl_exec($curl);
curl_close($curl);
return $result;

Acties:
  • 0 Henk 'm!

  • Red devil
  • Registratie: December 1999
  • Laatst online: 09:00
GlowMouse schreef op zaterdag 20 februari 2021 @ 20:58:
Je zou eens kunnen kijken of het xlsx-bestand een geldig zip-bestand is, om vervolgens de inhoud te vergelijken met de inhoud van een ander xlsx-bestand.
Goeie, de versie uit Java kan ik zo openen met 7-zip. Maar de versie gesaved via PHP niet -->

7-zip : An attempt was made to move the file pointer before the beginning of the file

Die ga ik eens googlen

Acties:
  • +1 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Red devil schreef op zaterdag 20 februari 2021 @ 21:00:
Goeie, de versie uit Java kan ik zo openen met 7-zip. Maar de versie gesaved via PHP niet -->

7-zip : An attempt was made to move the file pointer before the beginning of the file

Die ga ik eens googlen
Er zullen wel wat extra bytes in zitten. Kan je niet beter gewoon een hexdump van beide maken en daar met een diff-tool kijken of die op een specifieke plek zitten. Bijvoorbeeld allemaal vooraan of achteraan.

Je kan in ieder geval nu juist beter niet met high-level tools en checks gaan werken, want het gaat mis op een detailniveau waar die tools niks mee te maken hebben en je niks zinnigs over kunnen zeggen.

Het zou zomaar kunnen dat je bijvoorbeeld in de php-versie ook de response-headers van Java hebt meegenomen, ipv alleen de data.

Om dit laatste te checken kan je trouwens ook de php-versie in een teksteditor openen, die headers zouden er als platte tekst helemaal vooraan in staan dan.

Verder zou je nog kunnen controleren of de transfer-encoding van je java-versie wel ook binary is, als dat niet met elkaar overeenkomt zou het zomaar verkeerd kunnen gaan doordat je browser met de veranderde header ineens niet meer een specifieke decoding zou toepassen dan.

[ Voor 8% gewijzigd door ACM op 21-02-2021 07:59 ]


Acties:
  • 0 Henk 'm!

  • Red devil
  • Registratie: December 1999
  • Laatst online: 09:00
ACM schreef op zondag 21 februari 2021 @ 07:58:
[...]

Er zullen wel wat extra bytes in zitten. Kan je niet beter gewoon een hexdump van beide maken en daar met een diff-tool kijken of die op een specifieke plek zitten. Bijvoorbeeld allemaal vooraan of achteraan.

Je kan in ieder geval nu juist beter niet met high-level tools en checks gaan werken, want het gaat mis op een detailniveau waar die tools niks mee te maken hebben en je niks zinnigs over kunnen zeggen.

Het zou zomaar kunnen dat je bijvoorbeeld in de php-versie ook de response-headers van Java hebt meegenomen, ipv alleen de data.

Om dit laatste te checken kan je trouwens ook de php-versie in een teksteditor openen, die headers zouden er als platte tekst helemaal vooraan in staan dan.

Verder zou je nog kunnen controleren of de transfer-encoding van je java-versie wel ook binary is, als dat niet met elkaar overeenkomt zou het zomaar verkeerd kunnen gaan doordat je browser met de veranderde header ineens niet meer een specifieke decoding zou toepassen dan.
Je hebt gelijk. De werkende Excel, die ik lokaal save, is 16KB. De file die ik save via met PHP als tussenstation is 28 KB. Wel "lijken" ze beide op elkaar, allebei Content_Types].xml in de 1e regel in Notepad++.

In Java betreft het een SXSSFWorkbook die een write(OutputStream output) heeft. Aangezien ik de functie al binnenkom met een OutputStream (in AWS, Lambda procedure), gooi ik die OutputStream erin.


Maar het lijkt erop dat ik de Java headers mee neem, ik zal daar eens naar kijken. Thanks!

Acties:
  • 0 Henk 'm!

  • Red devil
  • Registratie: December 1999
  • Laatst online: 09:00
Ik heb nu maar een andere weg genomen. Duurt circa 1.5-2 sec langer. Ik save nu de Excel file rechtstreeks op S3. Vervolgens de S3 link terugsturen naar Laravel. Had daar al een routine om files te downloaden van s3 en naar een gebruiker te sturen. Dus die kon ik weer gebruiken, werkt nu prima.

* Red devil is pragmatisch
Pagina: 1