2017-11-23 3 views
8

Ich habe einen PDF-Export, der eine Weile dauert, um das PDF zu erstellen. Ich möchte, dass der Benutzer in der Lage ist, auf den Exportlink zu klicken und sofort mit einem Download-Dialog konfrontiert wird. Auf diese Weise können sie den Download starten und einfach darauf warten, bis der Download abgeschlossen ist. Anstatt auf den Link zu klicken, warten Sie auf die Generierung und warten Sie dann erneut auf den Download.Download-Dialog wird ausgelöst, nachdem die Header empfangen wurden

Hier ist ein sehr einfaches Beispiel in PHP:

<?php 

header('Content-Type: application/pdf'); 
header('Content-Disposition: attachment; filename=test.pdf'); 
flush(); 

// time consuming PDF creation happens here 
sleep(15); 
echo 'pdf contents would be here'; 

Die Idee ist, die entsprechenden Header, flush(), um sie an den Browser zu senden, langsam die PDF erstellen und schließlich an den Browser senden.

Dies funktioniert perfekt in Chrom. Der Download-Dialog erscheint sofort und der Schlaf ist Teil der Download-Wartezeit.

In Firefox und InternetExplorer funktioniert das nicht. Diese Browser warten die vollen 15 Sekunden, bevor der Downloaddialog angezeigt wird.

Irgendeine Idee, wie man den Downloaddialog sofort erscheint, würde sehr geschätzt werden.

Antwort

2

Einige Browser warten auf den eigentlichen Inhalt, bevor sie den Download-Dialog anzeigen. Die Lösung ist einfach: Senden Sie einige PDF-Inhalte, bevor Sie den PDF-Inhalt erstellen.

Warten Sie eine Minute. Wie schickst du etwas, bevor du es hast? Das klingt nach einer Zeitmaschine, oder? Mach dir keine Sorgen, es gibt einen Weg, um es zu umgehen.

PDF content starts with %PDF, so müssen Sie einfach %PDF vor dem Aufruf von flush() senden. Entfernen Sie nach Abschluss der PDF-Erstellung die ersten 4 Byte des neu erstellten PDF-Inhalts, bevor Sie ihn erneut ausgeben.

<?php 
// disable output buffering 
while (@ob_end_clean()); 

header('Content-Type: application/pdf'); 
header('Content-Disposition: attachment; filename=test.pdf'); 

// send some content to trigger the download dialog 
echo '%PDF'; 
flush(); 

// time consuming PDF creation happens here 
sleep(15); 
$pdfContent = '%PDF-pdf contents would be here'; 
echo substr($pdfContent, 4); 

Diese Lösung funktioniert in jeder Sprache, da sie sich nicht auf eine reine PHP-Funktion verlässt.

Wenn Sie das absolute Minimum machen wollen, können Sie auch 1 Byte % senden und dann nur das erste Byte vor dem Echo entfernen. Gleiches Ergebnis.

+0

Das ist meine Vermutung war, auch.Ich habe das schon versucht, aber es funktioniert nicht. Nur um sicher zu sein, habe ich Ihren Code in Firefox erneut ausprobiert. Es wartet immer noch 15 Sekunden, bevor der Downloaddialog erscheint. –

+0

@AndreasGohr Ich nehme an, dass Sie nur 'flush()' verwenden, weil Sie Ihre Ausgangspufferung bereits deaktiviert haben. Die Tatsache, dass es nicht funktioniert, bedeutet, dass Sie es nicht getan haben. Ich habe den Code aktualisiert, damit er funktioniert, unabhängig von der Konfiguration der Ausgabepufferung. – Rei

+0

Seltsam. Du hast Recht, ich dachte, ich hätte keinen Ausgabepuffer aktiviert, aber mit deinem Zusatz funktioniert es! Danke vielmals! –

0

Dies ist ein generelles Problem und steht in keiner bestimmten Sprache. Wir machen einen Prozess, um einige Zeit zu warten, bis die PDF-Generierung gemacht wird und starten dann unseren Download-Prozess.

Um auf die PDF-Generierung zu warten, verwenden wir eine sleep() -Funktion, um den Prozess auf eine bestimmte Zeit warten zu lassen - 15 wie erwähnt.

sleep(15) 

Jetzt können wir nicht flush() der leeren Inhalt vor Kopf der pdf zum Browser erzeugt. So können wir statischen Inhalt vor dem Kopf senden und unseren Flush-Prozess starten.

Und nach erfolgreicher PDF-Generierung können wir den zuvor hinzugefügten Inhalt entfernen und den aktualisierten Inhalt der Funktion flush() des Browsers hinzufügen.

So ist der Gesamt Code wäre,

<?php 

// Initialize the Basic Header 

ob_start(); // Start Buffering 
header('Content-Type: application/pdf'); 
header('Content-Disposition: attachment; filename=test.pdf'); 

// Adding content before the PDF Generation Process 
echo 'demo'; 

// Flushing content to the Browser 

ob_end_flush(); 
ob_flush(); 
flush(); 

// time consuming PDF creation happens here 
sleep(15); 

$Content = 'demoother pdf content'; 

// Removind the Added Content 
echo substr($Content, 4); 

?> 
+0

"* Um also auf die PDF-Generierung zu warten, verwenden wir die Funktion sleep() *". Das ist nicht der Zweck von 'sleep()' in der Frage. Nicht annähernd. Sie sollten die Frage erneut lesen und fragen, ob Sie immer noch nicht verstehen. – Rei

Verwandte Themen