2008-09-29 12 views
40

Mon application génère des fichiers PDF pour la consommation de l'utilisateur. L'en-tête http "Content-Disposition" est défini comme indiqué here. 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, en cliquant sur le bouton "Enregistrer" dans le navigateur Acrobat incorporé au navigateur, le nom par défaut à enregistrer n'est pas ce nom de fichier, mais l'URL avec des barres obliques transformées en traits de soulignement. Énorme et moche. Est-il possible d'affecter ce nom de fichier par défaut dans Adobe?"nom" web pdf pour mieux sauvegarder le nom de fichier par défaut dans Acrobat?

Il existe une chaîne de requête dans les URL, ce qui n'est pas négociable. Cela peut être significatif, 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é 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ée 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 un défaut Acrobat Enregistrer sous le nom de fichier

http___localhost_bar_sessions_958d8a22-0_views_1493881172_export_format=application_pdf&no-attachment=true.pdf

Mise à jour 3: Julian Reschke apporte un aperçu réel et de rigueur à ce cas. S'il vous plaît upvote 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

Répondre

10

Une partie du problème est que le RFC 2183 pertinent ne dit pas vraiment quoi faire avec un type de disposition "inline" et un nom de fichier. En outre, autant que je sache, le seul UA qui utilise réellement le nom de fichier pour type = inline est Firefox (voir test case).

Enfin, il n'est pas évident que l'API du plugin rende réellement cette information disponible (peut-être que certains familiers de l'API peuvent élaborer). Cela étant dit, j'ai envoyé un pointeur à cette question à une personne d'Adobe; Peut-être que les bonnes personnes vont jeter un coup d'oeil.Connexions: voir tentative de clarification de la disposition du contenu dans HTTP dans draft-reschke-rfc2183-in-http - il s'agit d'un travail en cours, les commentaires sont appréciés.

Mise à jour: J'ai ajouté un test case, ce qui semble indiquer que le plugin Acrobat Reader n'utilise pas les en-têtes de réponse (dans Firefox), bien que l'API du plugin leur donne accès.

+1

Y at-il une solution/contourner ce problème? –

+0

Je viens d'essayer d'ajouter content-disposition en ligne; filename = foo.pdf et il semble fonctionner dans Chrome, au moins. – gorantq

0

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.

+0

Désolé, mais je crois que ce serait pire (en ce qui concerne l'expérience utilisateur) que de ne rien faire. Renommer un fichier n'est pas une affaire énorme, juste un ennuyeux. –

+0

Assez juste. Gmail fait cela avec des images, et je l'aime bien personnellement. Bonne chance quand même :-) –

7

Définissez également le nom de 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 la tête de disposition de contenu, ajoutez-en-tête de longueur du contenu, puis utilisez également BinaryWrite pour diffuser le PDF.

context.Response.AddHeader("Content-Length", fileBytes.Length.ToString()); 
context.Response.BinaryWrite(fileBytes); 
+1

Il a déjà fait ça. Acrobat Reader l'ignore, à ce qu'il semble. –

+1

Suggestion est de définir ContentType = "application/pdf; nom = foo.pdf" dont il ne dit pas qu'il l'a essayé. – Vivek

+0

J'avais de grands espoirs, mais cela ne semble pas affecter Acrobat Reader 8.0 dans IE ou FF. Question mise à jour –

1

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

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

J'utilisé en ligne dans une application Web précédente qui a généré la sortie Crystal Reports en PDF et envoyés que dans le navigateur à l'utilisateur.

9

Comme vous, j'ai essayé de faire en sorte que cela fonctionne. Finalement j'ai abandonné cette idée, et j'ai juste opté pour une solution de contournement. J'utilise ASP.NET MVC Framework, j'ai donc modifié mes routes pour ce contrôleur/cette action pour m'assurer que le fichier PDF servi est la dernière partie de la partie location de l'URI (avant la chaîne de requête) et passez tout le reste dans la chaîne de requête.

Par exemple:

Ancien URI:

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

URI:

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

L'en-tête résultant ressemble exactement à ce que vous avez décrit (type de contenu est application/pdf, la disposition est inline, le nom de fichier fait inutilement partie de l'en-tête). Acrobat l'affiche dans la fenêtre du navigateur (aucune boîte de dialogue de sauvegarde) et le nom de fichier qui est rempli automatiquement 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 à regarder décent, ils ne devraient avoir aucun caractère échappé (c.-à-pas d'espaces, etc.) ... ce qui est un peu limite. Mes noms de fichiers sont générés automatiquement dans ce cas, et avant avaient des espaces dans ceux-ci, qui apparaissaient comme '% 20' dans le nom de fichier résultant de la boîte de dialogue de sauvegarde. J'ai juste remplacé les espaces avec des underscores, 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 le faire partie de l'URI d'origine, ce qui pourrait déranger le flux de travail de votre programme. Si elle est actuellement générée ou extraite d'une base de données 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 base de données appel ajax rapide pour obtenir le nom de fichier lors de la construction de l'URL qui résulte dans le PDF inline.

Si vous prenez le nom de fichier d'une entrée d'utilisateur sur un formulaire, cela devrait être validé pour ne pas contenir de caractères échappés, ce qui agace les utilisateurs.

Espérons que ça aide.

+0

Excellente idée. :) –

0

J'ai été redirigé ici parce que j'ai le même problème. J'ai également essayé la solution de contournement de Troy Howard, mais cela ne semble pas fonctionner.

L'approche que j'ai suivie sur celui-ci est de ne plus utiliser l'objet réponse pour écrire le fichier à la volée. Comme le PDF existe déjà sur le serveur, j'ai redirigé ma page vers ce fichier PDF. Fonctionne très bien.

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

J'espère que mon explication vague vous a donné une idée.

-1

Essayez cela, si votre exécutable est "get.cgi"

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

Oui, il 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 filename.pdf et le lecteur pdf ne tient pas compte du « get.cgi »

Dan

+0

Cela semble dépendre d'un bug dans votre serveur web? Cela devrait 404 selon les spécifications - Apache se comporte-t-il de cette façon? –

+0

Ce n'est pas * complètement * fou, et cela ne devrait pas forcément aboutir à un 404. Des chemins supplémentaires suivant un exécutable CGI sont valides, et devraient entraîner la définition de la variable CGI PATH_INFO. Cela dit, je ne pense pas que ce soit la façon la plus propre de résoudre ce problème. – asmecher

1

Je crois que cela a déjà été mentionné dans une saveur ou d'une autre, mais je vais essayer de le préciser dans mon 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'avoir procédé "à l'exportation" la demande, lorsqu'une demande arrive, je regarde dans l'URL pour GeneratePDF = 1. Si trouvé, j'exécute n'importe quel code qui s'exécute dans "export" plutôt que de permettre à mon système d'essayer de chercher et de servir un PDF à 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 rediriger vers le fichier demandé - sinon je finirais dans une boucle sans fin)

2

Si vous utilisez asp.net, vous pouvez contrôler le nom de fichier pdf par le biais du nom de fichier de la page (url). Comme d'autres utilisateurs ont écrit, Acrobat est un peu s ... quand il choisit le nom du fichier pdf lorsque vous appuyez sur le bouton "Enregistrer": 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 je trouve est de gérer les noms de page « dynamiques » par un gestionnaire d'asp.net:

  • créer une classe qui implémente IHttpHandler
  • carte un gestionnaire dans le Web.config limitée à la classe

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

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

Mapping2: nom de fichier entièrement gratuit (besoin d'un dossier dans le chemin):

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

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

0

La façon dont j'ai résolu ceci (avec PHP) est la suivante:

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

Modifiez 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 vous voulez qu'Adobe utilise (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']); 

ajouter 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 $_REQUEST (ou $_GET si vous préférez) est accédé comme normal $_REQUEST['id'], $_REQUEST['data'], etc.

Et Ado be utilisera votre nom de fichier désiré comme enregistrement par défaut ou email info lorsque vous l'envoyez en ligne.

0

Pour tous ceux qui cherchent encore à cela, j'ai utilisé la solution trouvée here et cela a fonctionné à merveille. Merci Fabrizio!

+0

Downvoted car lien uniquement. –

1

dialogue de téléchargement de fichier (PDF) avec enregistrer et option ouverte

Points à retenir:

  1. Retour flux avec bonne taille du tableau du service
  2. Lire le arrary octet de flux avec une longueur d'octets correct sur la base de la longueur du cours d'eau.
  3. jeu correct contenttype

Voici le code pour le flux de lecture et ouvrez la boîte de dialogue de téléchargement de fichier pour le 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(); 
    } 
} 
4

Dans le changement ASP.NET 2.0 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 SaveAs est maintenant MySaveAsFileName.pdf.

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

4

Apache's mod_rewrite peut résoudre ce problème.

J'ai un service Web avec un point d'extrémité à /foo/getDoc.service. Bien sûr, Acrobat enregistrera les fichiers en tant que 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éécrite en interne à /foo/getDoc.service?bar&qux, donc je suis frapper le point final correct du service Web, mais Acrobat pense qu'il sauvera mon dossier comme filename.pdf.

Questions connexes