“Nom” web pdf pour un meilleur nom de sauvegarde par défaut dans Acrobat?

Mon application génère des fichiers PDF pour la consommation des utilisateurs. L’en-tête http “Content-Disposition” est défini comme indiqué ici . Ceci est défini sur “inline; filename = foo.pdf“, ce qui devrait suffire à Acrobat pour donner “foo.pdf” comme nom de fichier lors de la sauvegarde du pdf.

Cependant, lorsque vous cliquez sur le bouton “Enregistrer” dans Acrobat intégré au navigateur, le nom par défaut à enregistrer n’est pas ce nom de fichier, mais l’URL avec des barres obliques est remplacée par des traits de soulignement. Énorme et moche. Existe-t-il un moyen d’affecter ce nom de fichier par défaut dans Adobe?

Il y a une chaîne de requête dans les URL, et cela n’est pas négociable. Cela peut être important, mais l’ajout d’un “& foo = / title.pdf” à la fin de l’URL n’affecte pas le nom de fichier par défaut.

Mise à jour 2: j’ai essayé les deux

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

et

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

(comme vérifié par Firebug) Malheureusement, ni travaillé.

Un exemple d’URL est

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

qui se traduit par une sauvegarde Acrobat par défaut comme nom de fichier de

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

Mise à jour 3: Julian Reschke apporte un éclairage et une rigueur à cette affaire. S’il vous plaît, donnez sa réponse. Cela semble être cassé dans FF ( https://bugzilla.mozilla.org/show_bug.cgi?id=433613 ) et IE mais fonctionne dans Opera, Safari et Chrome. http://greenbytes.de/tech/tc2231/#inlwithasciifilenamepdf

Une partie du problème réside dans le fait que la RFC 2183 concernée ne précise pas vraiment ce qu’il faut faire avec un type de disposition “inline” et un nom de fichier.

Aussi, pour autant que je sache, le seul UA qui utilise réellement le nom de fichier pour le type = inline est Firefox (voir le scénario de test ).

Enfin, il n’est pas évident que l’API du plug-in rende ces informations disponibles (peut-être que certains utilisateurs familiers de l’API peuvent élaborer).

Cela étant dit, j’ai envoyé un pointeur sur cette question à une personne Adobe. peut-être que les bonnes personnes vont regarder.

Connexe: voir la tentative de clarification de Content-Disposition en HTTP dans draft-reschke-rfc2183-in-http – c’est un travail en cours, les commentaires sont appréciés.

Mise à jour: J’ai ajouté un scénario de test , qui semble indiquer que le plug-in Acrobat Reader n’utilise pas les en-têtes de réponse (dans Firefox), bien que l’API du plug-in leur permette d’y accéder.

Définissez également le nom du fichier dans ContentType . Cela devrait résoudre le problème.

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

Après avoir défini l’en-tête de disposition du contenu, ajoutez également un en-tête de longueur de contenu, puis utilisez binarywrite pour diffuser le PDF.

 context.Response.AddHeader("Content-Length", fileBytes.Length.ToSsortingng()); context.Response.BinaryWrite(fileBytes); 

Comme vous, j’ai essayé et essayé de faire en sorte que cela fonctionne. Finalement, j’ai abandonné cette idée et j’ai opté pour une solution de contournement.

J’utilise ASP.NET MVC Framework, j’ai donc modifié mes itinéraires pour ce contrôleur / action pour m’assurer que le fichier PDF fourni est la dernière partie de la partie d’emplacement de l’URI (avant la chaîne de requête) et tout transmettre sinon dans la chaîne de requête.

Par exemple:

Vieux URI:

http: // server / app / report / showpdf? param1 = foo & param2 = barre & nom de fichier = myreport.pdf

Nouveau URI:

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

L’en-tête résultant ressemble exactement à ce que vous avez décrit (content-type est application / pdf, la disposition est en ligne, le nom de fichier fait partie intégrante de l’en-tête). Acrobat le montre dans la fenêtre du navigateur (pas de boîte de dialog d’enregistrement) et le nom du fichier qui est automatiquement rempli si un utilisateur clique sur le bouton Acrobat Save est le nom du fichier de rapport.

Quelques considérations:

Pour que les noms de fichiers soient corrects, ils ne devraient contenir aucun caractère échappé (c.-à-d. Pas d’espaces, etc.) … ce qui est un peu limitant. Mes noms de fichiers sont générés automatiquement dans ce cas, et auparavant, ils comportaient des espaces qui apparaissaient sous la forme «% 20» dans le nom du fichier de sauvegarde résultant. Je viens de remplacer les espaces par des traits de soulignement, et cela a fonctionné.

Ce n’est en aucun cas la meilleure solution, mais cela fonctionne. Cela signifie également que vous devez avoir le nom de fichier disponible pour qu’il fasse partie de l’URI d’origine, ce qui pourrait perturber le stream de travail de votre programme. S’il est actuellement généré ou extrait d’une firebase database lors de l’appel côté serveur qui génère le PDF, vous devrez peut-être déplacer le code qui génère le nom de fichier en JavaScript dans le cadre d’une soumission de formulaire ou s’il provient d’une firebase database. Appel ajax rapide pour obtenir le nom du fichier lors de la création de l’URL qui génère le fichier PDF intégré.

Si vous prenez le nom de fichier à partir d’une entrée d’utilisateur sur un formulaire, cela doit être validé pour ne pas contenir de caractères échappés, ce qui gênera les utilisateurs.

J’espère que cela pourra aider.

Essayez de placer le nom du fichier à la fin de l’URL, avant tout autre paramètre. Cela a fonctionné pour moi. http://www.setasign.de/support/tips-and-sortingcks/filename-in-browser-plugin/

Dans ASP.NET 2.0, modifiez l’URL de

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

à

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

Cela fonctionne pour Acrobat 8 ​​et le nom de fichier par défaut de SaveAs est maintenant MySaveAsFileName.pdf .

Cependant, vous devez restreindre les caractères autorisés dans MySaveAsFileName (pas de point, etc.).

Le mod_rewrite d’Apache peut résoudre ce problème.

J’ai un service Web avec un sharepoint terminaison sur /foo/getDoc.service . Bien sûr, Acrobat enregistre les fichiers sous le nom getDoc.pdf . J’ai ajouté les lignes suivantes dans apache.conf :

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

Maintenant, quand je demande /foo/getDoc/filename.pdf?bar&qux , il est réécrit en interne dans /foo/getDoc.service?bar&qux , donc je trouve le bon sharepoint terminaison du service Web, mais Acrobat pense qu’il va enregistrer mon fichier comme filename.pdf .

Si vous utilisez asp.net, vous pouvez contrôler le nom de fichier pdf via le nom de fichier de la page (URL). Comme d’autres utilisateurs l’ont écrit, Acrobat est un peu … quand il choisit le nom du fichier pdf lorsque vous appuyez sur le bouton “save”: il prend le nom de la page, supprime l’extension et ajoute “.pdf”. Donc /foo/bar/GetMyPdf.aspx donne GetMyPdf.pdf.

La seule solution que j’ai trouvée consiste à gérer les noms de page “dynamics” via un gestionnaire asp.net:

  • créer une classe qui implémente IHttpHandler
  • mapper un gestionnaire dans web.config lié à la classe

Mapping1: toutes les pages ont une base commune (MyDocument_):

   

Mapping2: nom de fichier complètement libre (nécessite un dossier dans le chemin):

  

Quelques astuces ici (le pdf est créé dynamicment avec iTextSharp):
http://fhtino.blogspot.com/2006/11/how-to-show-or-download-pdf-file-from.html

Au lieu de pièce jointe, vous pouvez essayer en ligne:

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

J’ai utilisé en ligne une application Web précédente qui générait une sortie Crystal Reports au format PDF et l’envoyait dans un navigateur à l’utilisateur.

Boîte de dialog de téléchargement de fichier (PDF) avec option d’enregistrement et d’option

Points à retenir:

  1. Flux de retour avec la taille de tableau correcte du service
  2. Lire le byte arret du stream avec la longueur d’octet correcte sur la base de la longueur du stream.
  3. définir le type de contenu correct

Voici le code du stream de lecture et ouvrez la boîte de dialog de téléchargement du fichier PDF

 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(); } } 

Je crois que cela a déjà été mentionné dans une saveur ou une autre mais je vais essayer de le dire dans mes propres mots.

Plutôt que ceci:

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

J’utilise ceci:

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

Plutôt que d’exporter la requête, lorsqu’une requête arrive, je cherche dans l’URL de GeneratePDF = 1. Si trouvé, j’exécute n’importe quel code exécuté dans “export” plutôt que de permettre à mon système de tenter de rechercher et de servir un PDF dans l’emplacement /bar/sessions/958d8a22-0/views/1493881172/NameThatIWantPDFToBe.pdf . Si GeneratePDF n’est pas trouvé dans l’URL, je transmets simplement le fichier demandé. (notez que je ne peux pas simplement redirect vers le fichier demandé – sinon je me retrouverais dans une boucle sans fin)

Vous pouvez toujours avoir deux liens. Un qui ouvre le document dans le navigateur et un autre pour le télécharger (en utilisant un type de contenu incorrect). C’est ce que fait Gmail.

Pour ceux qui regardent encore cela, j’ai utilisé la solution trouvée ici et cela a fonctionné à merveille. Merci Fabrizio!

La façon dont j’ai résolu ce problème (avec PHP) est la suivante:

Supposons que votre URL soit SomeScript.php?id=ID&data=DATA et que le fichier que vous voulez utiliser est TEST.pdf .

Changez l’URL en SomeScript.php/id/ID/data/DATA/EXT/TEST.pdf .

Il est important que le dernier paramètre soit le nom de fichier que Adobe souhaite utiliser (le «EXT» peut concerner n’importe quoi). Assurez-vous qu’il n’y a pas de caractères spéciaux dans la chaîne ci-dessus, BTW.

Maintenant, en haut de SomeScript.php , ajoutez:

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

Ajoutez ensuite cette fonction à SomeScript.php (ou à votre bibliothèque de fonctions):

 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 

Maintenant on $_REQUEST (ou $_GET si vous préférez) comme $_REQUEST['id'] , $_REQUEST['data'] , etc.

Et Adobe utilisera votre nom de fichier désiré comme enregistrement par défaut ou comme info e-mail lorsque vous l'envoyez en ligne.

J’ai été redirigé ici parce que j’ai le même problème. J’ai aussi essayé la solution de rechange de Troy Howard, mais ça ne semble pas fonctionner.

L’approche que j’ai adoptée sur celui-ci consiste à ne plus utiliser d’object de réponse pour écrire le fichier à la volée. Étant donné que le PDF existe déjà sur le serveur, ce que j’ai fait était de redirect ma page pointant vers ce fichier PDF. Fonctionne très bien.

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

J’espère que ma vague explication vous a donné une idée.

Crédits à 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; } 

Vérifier avec

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

Firefox 62.0b5 (64 bits): OK.

Chrome 67.0.3396.99 (64 bits): OK.

IE 11: Aucun commentaire.

Essayez ceci, si votre exécutable est “get.cgi”

http: //server,org/get.cgi/filename.pdf? file = nomfichier.pdf

Oui, c’est complètement fou. Il n’y a pas de fichier appelé “filename.pdf” sur le serveur, il y a du répertoire sous l’exécutable get.cgi.

Mais cela semble fonctionner. Le serveur ignore le nom de fichier.pdf et le lecteur de pdf ignore le “get.cgi”

Dan