Toon posts:

[PHP] save bytes uit response naar XLXS file

Pagina: 1
Acties:

Vraag


  • Red devil
  • Registratie: December 1999
  • Nu online
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:



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


  • 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}


  • 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.

  • Red devil
  • Registratie: December 1999
  • Nu online
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;

  • Red devil
  • Registratie: December 1999
  • Nu online
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

  • 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]


  • Red devil
  • Registratie: December 1999
  • Nu online
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!

  • Red devil
  • Registratie: December 1999
  • Nu online
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


Tweakers maakt gebruik van cookies

Tweakers plaatst functionele en analytische cookies voor het functioneren van de website en het verbeteren van de website-ervaring. Deze cookies zijn noodzakelijk. Om op Tweakers relevantere advertenties te tonen en om ingesloten content van derden te tonen (bijvoorbeeld video's), vragen we je toestemming. Via ingesloten content kunnen derde partijen diensten leveren en verbeteren, bezoekersstatistieken bijhouden, gepersonaliseerde content tonen, gerichte advertenties tonen en gebruikersprofielen opbouwen. Hiervoor worden apparaatgegevens, IP-adres, geolocatie en surfgedrag vastgelegd.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Toestemming beheren

Hieronder kun je per doeleinde of partij toestemming geven of intrekken. Meer informatie vind je in ons cookiebeleid.

Functioneel en analytisch

Deze cookies zijn noodzakelijk voor het functioneren van de website en het verbeteren van de website-ervaring. Klik op het informatie-icoon voor meer informatie. Meer details

janee

    Relevantere advertenties

    Dit beperkt het aantal keer dat dezelfde advertentie getoond wordt (frequency capping) en maakt het mogelijk om binnen Tweakers contextuele advertenties te tonen op basis van pagina's die je hebt bezocht. Meer details

    Tweakers genereert een willekeurige unieke code als identifier. Deze data wordt niet gedeeld met adverteerders of andere derde partijen en je kunt niet buiten Tweakers gevolgd worden. Indien je bent ingelogd, wordt deze identifier gekoppeld aan je account. Indien je niet bent ingelogd, wordt deze identifier gekoppeld aan je sessie die maximaal 4 maanden actief blijft. Je kunt deze toestemming te allen tijde intrekken.

    Ingesloten content van derden

    Deze cookies kunnen door derde partijen geplaatst worden via ingesloten content. Klik op het informatie-icoon voor meer informatie over de verwerkingsdoeleinden. Meer details

    janee