webentwicklung-frage-antwort-db.com.de

"Name" Web-PDF für besseren Standard-Dateinamen in Acrobat speichern?

Meine App generiert PDF-Dateien für die Verwendung durch den Benutzer. Der http-Header "Content-Disposition" wird wie angegeben gesetzt here . Dies ist auf "inline; Dateiname = foo.pdf" eingestellt. Dies sollte ausreichen, damit Acrobat beim Speichern der PDF-Datei "foo.pdf" als Dateinamen angibt.

Beim Klicken auf die Schaltfläche "Speichern" im in Acrobat eingebetteten Browser ist der zu speichernde Standardname jedoch nicht der Dateiname, sondern die URL mit Schrägstrichen wurde in Unterstriche geändert. Riesig und hässlich. Gibt es eine Möglichkeit, diesen Standarddateinamen in Adobe zu beeinflussen?

There IS eine Abfragezeichenfolge in den URLs, und dies ist nicht verhandelbar. Dies kann von Bedeutung sein, aber das Hinzufügen einer "& foo =/title.pdf" am Ende der URL wirkt sich nicht auf den Standarddateinamen aus.

Update 2: Ich habe beide ausprobiert

content-disposition  inline; filename=foo.pdf
Content-Type         application/pdf; filename=foo.pdf

und

content-disposition  inline; filename=foo.pdf
Content-Type         application/pdf; name=foo.pdf

(wie durch Firebug bestätigt) Leider funktionierte keiner.

Eine Beispiel-URL ist

/ bar/Sitzungen/958d8a22-0/views/1493881172/export? format = application/pdf & no-attachment = true

dies wird in einen Standard-Acrobat-Speicher als Dateiname von übersetzt

http ___ localhost_bar_sessions_958d8a22-0_views_1493881172_export_format = application_pdf & no-attachment = true.pdf

Update 3: Julian Reschke bringt in diesen Fall tatsächliche Einsicht und Strenge. Bitte stimmen Sie seine Antwort .. .. Dies scheint in FF ( https://bugzilla.mozilla.org/show_bug.cgi?id=433613 ) und IE zu sein, funktioniert aber in Opera , Safari und Chrome. http://greenbytes.de/tech/tc2231/#inlwithasciifilenamepdf

42
James Baker

Ein Teil des Problems ist, dass der relevante RFC 2183 nicht wirklich angibt, was mit einem Dispositionstyp "inline" und einem Dateinamen zu tun ist.

Soweit ich das beurteilen kann, ist Firefox der einzige UA, der den Dateinamen für type = inline verwendet (siehe test case ).

Schließlich ist es nicht offensichtlich, dass die Plugin-API diese Informationen tatsächlich zur Verfügung stellt (vielleicht kann jemand, der mit der API vertraut ist, etwas ausarbeiten).

Davon abgesehen habe ich einen Zeiger auf diese Frage an eine Adobe-Person gesendet. Vielleicht haben die richtigen Leute einen Blick darauf.

Siehe auch: Versuch, die Inhaltsdisposition in HTTP in draft-reschke-rfc2183-in-http zu klären - dies ist eine frühe Arbeit in Arbeit, Feedback wird geschätzt.

Update: Ich habe einen Testfall hinzugefügt, der andeutet, dass das Acrobat Reader Plugin die Antwortheader (in Firefox) nicht verwendet, obwohl die Plugin-API Zugriff darauf bietet.

10
Julian Reschke

Legen Sie denDateinamen in ContentType ebenfalls fest. Dies sollte das Problem lösen.

context.Response.ContentType = "application/pdf; name=" + fileName;
// the usual stuff
context.Response.AddHeader("content-disposition", "inline; filename=" + fileName);

Fügen Sie nach dem Festlegen des Inhalts-Dispositions-Headers auch den Content-Length-Header hinzu und streamen Sie dann die Datei mit Binarywrite.

context.Response.AddHeader("Content-Length", fileBytes.Length.ToString());
context.Response.BinaryWrite(fileBytes);
9
Vivek

Wie Sie habe ich versucht und versucht, dies zum Laufen zu bringen. Schließlich gab ich diese Idee auf und entschied mich für einen Workaround. 

Ich verwende ASP.NET MVC Framework. Daher habe ich meine Routen für diesen Controller/diese Aktion geändert, um sicherzustellen, dass die bereitgestellte PDF -Datei der letzte Teil des Speicherbereichs der URI ist (vor der Abfragezeichenfolge). und übergeben Sie alles andere in der Abfragezeichenfolge. 

Z.B: 

Alte URI: 

http: // server/app/report/showpdf? param1 = foo & param2 = bar & dateiname = meinbericht.pdf

Neue URI: 

http: //server/app/report/showpdf/myreport.pdf? param1 = foo & param2 = bar

Der resultierende Header sieht genau so aus, wie Sie ihn beschrieben haben (Inhaltstyp ist application/pdf, Disposition ist Inline, Dateiname ist unnötig Teil des Headers). Acrobat zeigt es im Browserfenster an (kein Dialogfeld "Speichern unter"). Der Dateiname, der automatisch ausgefüllt wird, wenn ein Benutzer auf die Acrobat-Schaltfläche "Speichern" klickt, ist der Berichtsdateiname.

Einige Überlegungen:

Damit die Dateinamen anständig aussehen, sollten sie keine Escape-Zeichen (dh keine Leerzeichen usw.) enthalten ... was ein wenig einschränkend ist. Meine Dateinamen werden in diesem Fall automatisch generiert und davor waren Leerzeichen enthalten, die als '% 20' im resultierenden Dateinamen des Sicherungsdialogfelds angezeigt wurden. Ich habe nur die Leerzeichen durch Unterstriche ersetzt, und das hat funktioniert.

Dies ist keineswegs die beste Lösung, aber es funktioniert. Das bedeutet auch, dass Sie den Dateinamen zur Verfügung haben müssen, um ihn in den ursprünglichen URI zu integrieren, der den Workflow Ihres Programms beeinträchtigen kann. Wenn er während des serverseitigen Aufrufs, der die PDF-Datei generiert, derzeit aus einer Datenbank generiert oder abgerufen wird, müssen Sie möglicherweise den Code, der den Dateinamen generiert, als Teil einer Formularübergabe nach Javascript verschieben, oder wenn er aus einer Datenbank stammt Schneller Ajax-Aufruf, um den Dateinamen zu erhalten, wenn die URL erstellt wird, die zur eingebetteten PDF-Datei führt.

Wenn Sie den Dateinamen aus einer Benutzereingabe in einem Formular entnehmen, sollte überprüft werden, dass keine Escape-Zeichen enthalten sind, die die Benutzer stören.

Hoffentlich hilft das.

9
Troy Howard

Platzieren Sie den Dateinamen am Ende der URL vor allen anderen Parametern. Das hat für mich funktioniert . http://www.setasign.de/support/tips-and-tricks/filename-in-browser-plugin/

5
tekkgurrl

Apaches mod_rewrite kann dieses Problem lösen.

Ich habe einen Webservice mit einem Endpunkt unter /foo/getDoc.service. Natürlich speichert Acrobat Dateien als getDoc.pdf. Ich habe die folgenden Zeilen in Apache.conf hinzugefügt:

LoadModule     RewriteModule         modules/mod_rewrite.so
RewriteEngine  on
RewriteRule    ^/foo/getDoc/(.*)$    /foo/getDoc.service     [P,NE]

Wenn ich nun /foo/getDoc/filename.pdf?bar&qux anfordert, wird er intern in /foo/getDoc.service?bar&qux umgeschrieben. Ich stoße also auf den korrekten Endpunkt des Web-Service. Acrobat geht jedoch davon aus, dass meine Datei als filename.pdf gespeichert wird.

4
Mark Nettle

In ASP.NET 2.0 ändern Sie die URL von 

http://www. server.com/DocServe.aspx?DocId=XXXXXXX

zu 

http://www. server.com/DocServe.aspx/MySaveAsFileName?DocId=XXXXXXX

Dies funktioniert für Acrobat 8 ​​und der standardmäßige SaveAs-Dateiname ist jetzt MySaveAsFileName.pdf

Sie müssen jedoch die zulässigen Zeichen in MySaveAsFileName einschränken (keine Punkte usw.).

4
Karsten

Wenn Sie asp.net verwenden, können Sie den Dateinamen von PDF-Dateien über den Dateinamen der Seite (URL) steuern .. .. Wie andere Benutzer bereits geschrieben haben, ist Acrobat ein bisschen s ... wenn Sie den PDF-Dateinamen auswählen, wenn Sie auf die Schaltfläche "Speichern" klicken : Er nimmt den Seitennamen, entfernt die Erweiterung und fügt ".pdf" hinzu. So gibt /foo/bar/GetMyPdf.aspx GetMyPdf.pdf ein.

Die einzige Lösung, die ich gefunden habe, ist die Verwaltung "dynamischer" Seitennamen über einen asp.net -Handler: 

  • erstellen Sie eine Klasse, die IHttpHandler implementiert 
  • ordnen Sie einen Handler in web.config zu, der an die Klasse gebunden ist

Mapping1: Alle Seiten haben eine gemeinsame Basis (MyDocument_):

<httpHandlers>  
<add verb="*" path="MyDocument_*.ashx" type="ITextMiscWeb.MyDocumentHandler"/>

Mapping2: vollständig freier Dateiname (benötigt einen Ordner im Pfad): 

<add verb="*" path="/CustomName/*.ashx" type="ITextMiscWeb.MyDocumentHandler"/>

Einige Tipps hier (das PDF wird dynamisch mit iTextSharp erstellt):
http://fhtino.blogspot.com/2006/11/wie-nach-show-oder-download-pdf-datei-von.html

2

Anstelle des Anhangs können Sie online versuchen:

Response.AddHeader("content-disposition", "inline;filename=MyFile.pdf");

Ich verwende Inline in einer früheren Webanwendung, die Crystal Reports-Ausgaben in PDF generiert und diese im Browser an den Benutzer gesendet hat.

1
ManiacZX

Ich glaube, das wurde schon in der einen oder anderen Richtung erwähnt, aber ich versuche es in meinen eigenen Worten.

Lieber als das:

/bar/sessions/958d8a22-0/views/1493881172/export?format=application/pdf&no-attachment=true

Ich benutze das:

/bar/sessions/958d8a22-0/views/1493881172/NameThatIWantPDFToBe.pdf?GeneratePDF=1

Anstatt die Anforderung "exportieren" zu lassen, schaue ich in der URL nach GeneratePDF = 1, wenn eine Anforderung eingeht. Falls gefunden, führe ich den Code aus, der im Export ausgeführt wurde, anstatt meinem System zu erlauben, eine PDF im Speicherort /bar/sessions/958d8a22-0/views/1493881172/NameThatIWantPDFToBe.pdf zu suchen. Wenn GeneratePDF nicht in der URL gefunden wird, übertrage ich einfach die angeforderte Datei. (Beachten Sie, dass ich nicht einfach zu der angeforderten Datei umleiten kann - andernfalls würde ich in einer Endlosschleife enden.)

1
Matt

Dateidownload-Dialog (PDF) mit Option zum Speichern und Öffnen

Punkte, die man sich merken sollte:

  1. Stream mit korrekter Arraygröße vom Dienst zurückgeben
  2. Lesen Sie den Bytearar mit der korrekten Byte-Länge anhand der Stream-Länge aus dem Stream.
  3. setze den richtigen Inhaltstyp

Hier ist der Code für den Lesestream, und öffnen Sie den Dateidownload-Dialog für PDF Datei

private void DownloadSharePointDocument()
{
    Uri uriAddress = new Uri("http://hyddlf5187:900/SharePointDownloadService/FulfillmentDownload.svc/GetDocumentByID/1/drmfree/");
    HttpWebRequest req = WebRequest.Create(uriAddress) as HttpWebRequest;
    // Get response   
    using (HttpWebResponse httpWebResponse = req.GetResponse() as HttpWebResponse)
    {
        Stream stream = httpWebResponse.GetResponseStream();
        int byteCount = Convert.ToInt32(httpWebResponse.ContentLength);
        byte[] Buffer1 = new byte[byteCount];
        using (BinaryReader reader = new BinaryReader(stream))
        {
            Buffer1 = reader.ReadBytes(byteCount);
        }
        Response.Clear();
        Response.ClearHeaders();
        // set the content type to PDF 
        Response.ContentType = "application/pdf";
        Response.AddHeader("Content-Disposition", "attachment;filename=Filename.pdf");
        Response.Buffer = true;
        Response.BinaryWrite(Buffer1);
        Response.Flush();
       // Response.End();
    }
}
1
Sunder Chhokar

Ich wurde hier umgeleitet, weil ich das gleiche Problem habe. Ich habe auch Troy Howards Workaround ausprobiert, aber es scheint nicht zu funktionieren.

Der Ansatz, den ich bei diesem Ansatz verwendet habe, ist, KEIN LÄNGER das Antwortobjekt zu verwenden, um die Datei im Handumdrehen zu schreiben. Da das PDF bereits auf dem Server vorhanden ist, habe ich meine Seite umgeleitet, die auf diese PDF -Datei zeigt. Funktioniert super.

http://forums.asp.net/t/143631.aspx

Ich hoffe, meine vage Erklärung gab Ihnen eine Idee.

0
mark

Sie könnten immer zwei Links haben. Eine, die das Dokument im Browser öffnet, und eine andere, um es herunterzuladen (mit einem falschen Inhaltstyp). Dies ist, was Gmail tut.

0
Vincent McNabb

Für jeden, der sich das noch anschaut, habe ich die gefundene Lösung hier verwendet und es hat wunderbar funktioniert. Danke Fabrizio!

0
Brian

Wie ich das gelöst habe (mit PHP) ist wie folgt:

Angenommen, Ihre URL ist SomeScript.php?id=ID&data=DATA und die Datei, die Sie verwenden möchten, ist TEST.pdf.

Ändern Sie die URL in SomeScript.php/id/ID/data/DATA/EXT/TEST.pdf.

Es ist wichtig, dass der letzte Parameter der Dateiname ist, den Adobe verwenden soll (der 'EXT' kann sich auf irgendetwas beziehen). Stellen Sie sicher, dass in der obigen Zeichenfolge keine Sonderzeichen (BTW) enthalten sind.

Fügen Sie am oberen Rand von SomeScript.php Folgendes hinzu:

$_REQUEST = MakeFriendlyURI( $_SERVER['PHP\_SELF'], $_SERVER['SCRIPT_FILENAME']);

Fügen Sie diese Funktion dann zu SomeScript.php (oder Ihrer Funktionsbibliothek) hinzu:

function MakeFriendlyURI($URI, $ScriptName) {

/* Need to remove everything up to the script name */
$MyName = '/^.*'.preg_quote(basename($ScriptName)."/", '/').'/';
$Str = preg_replace($MyName,'',$URI);
$RequestArray = array();

/* Breaks down like this
      0      1     2     3     4     5
    PARAM1/VAL1/PARAM2/VAL2/PARAM3/VAL3
*/

$tmp = explode('/',$Str);   
/* Ok so build an associative array with Key->value
   This way it can be returned back to $_REQUEST or $_GET
 */
for ($i=0;$i < count($tmp); $i = $i+2){
    $RequestArray[$tmp[$i]] = $tmp[$i+1];
}
return $RequestArray;       
}//EO MakeFriendlyURI

Jetzt wird auf $_REQUEST (oder $_GET, wenn Sie es vorziehen) wie normaler $_REQUEST['id'], $_REQUEST['data'] usw. zugegriffen.

Adobe verwendet Ihren gewünschten Dateinamen als Standardspeicher- oder E-Mail-Adresse, wenn Sie ihn online senden.

0
Rick Cooper

Kredite an Vivek .


Nginx

location /file.pdf
{
    # more_set_headers "Content-Type: application/pdf; name=save_as_file.pdf";
    add_header Content-Disposition "inline; filename=save_as_file.pdf";
    alias /var/www/file.pdf;
}

Überprüfen Sie mit

curl -I https://example.com/file.pdf

Firefox 62.0b5 (64-Bit): OK.

Chrome 67.0.3396.99 (64-Bit): OK.

IE 11: Kein Kommentar.

0
qräbnö