web-dev-qa-db-ja.com

Acrobatでのデフォルトの保存ファイル名を改善するための "name" web pdf?

私のアプリはユーザーが使用するPDFを生成します。 「Content-Disposition」httpヘッダーは、前述のように設定されています here 。これは "inline; filename = foo.pdf"に設定されます。これは、AcrobatがPDFを保存するときにファイル名として "foo.pdf"を指定するのに十分なはずです。

ただし、ブラウザに埋め込まれたAcrobatの[保存]ボタンをクリックすると、保存するデフォルトの名前はそのファイル名ではなく、スラッシュを含むURLがアンダースコアに変更されます。巨大で醜い。 Adobeでこのデフォルトのファイル名に影響を与える方法はありますか?

IS URLにクエリ文字列があり、これは交渉不可能です。これは重要な場合がありますが、URLの末尾に「&foo =/title.pdf」を追加してもデフォルトのファイル名に影響します。

更新2:両方を試しました

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

そして

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

(Firebugで確認済み)残念ながら、どちらも機能しませんでした。

サンプルURLは

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

ファイル名としてデフォルトのAcrobat保存に変換されます

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

更新3:Julian Reschkeは、このケースに実際の洞察と厳密さをもたらします。彼の答えに賛成投票してください。これはFF( https://bugzilla.mozilla.org/show_bug.cgi?id=43361 )とIEで壊れているようですが、Opera、Safariで動作しますおよびChrome http://greenbytes.de/tech/tc2231/#inlwithasciifilenamepdf

42
James Baker

問題の一部は、関連する RFC 218 が、「インライン」の処理タイプとファイル名の処理方法を実際に述べていないことです。

また、私の知る限り、type = inlineのファイル名を実際に使用しているUAはFirefoxのみです( test case を参照)。

最後に、プラグインAPIが実際にその情報を利用できるようにすることは明らかではありません(おそらくAPIに精通している誰かが詳しく説明できるでしょう)。

そうは言っても、私はこの質問へのポインタをアドビの人に送りました。たぶん、適切な人々が見るでしょう。

関連: draft-reschke-rfc2183-in-http のHTTPでContent-Dispositionを明確にする試みを参照してください。これは進行中の初期の作業であり、フィードバックを歓迎します。

更新: テストケース を追加しました。これは、Acrobatリーダープラグインが(Firefoxで)応答ヘッダーを使用しないことを示しているようですが、プラグインAPIはそれらにアクセスできます。

10
Julian Reschke

ContentTypeにもファイル名を設定します。これで問題が解決するはずです。

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

Content-dispositionヘッダーを設定した後、content-lengthヘッダーも追加し、binarywriteを使用してPDFをストリーミングします。

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

あなたのように、私はこれを動かしてみました。最後に、私はこの考えをあきらめ、回避策を選びました。

私はASP.NET MVCフレームワークを使用しているので、そのコントローラー/アクションのルートを変更して、提供されるPDFファイルがURIのロケーション部分の最後の部分であることを確認します(クエリ文字列の前に)、クエリ文字列の他のすべてを渡します。

例えば:

古い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

結果のヘッダーは、説明した内容とまったく同じです(コンテンツタイプはapplication/pdf、処理はインライン、ファイル名は無意味にヘッダーの一部です)。 Acrobatはそれをブラウザーウィンドウに表示し(ダイアログとして保存しない)、ユーザーがAcrobatの[保存]ボタンをクリックした場合に自動入力されるファイル名がレポートのファイル名です。

いくつかの考慮事項:

ファイル名がきちんと見えるようにするには、エスケープ文字(つまり、スペースなど)があってはなりません...これは少し制限があります。この場合、ファイル名は自動生成され、以前はスペースが含まれていたため、結果の保存ダイアログのファイル名に '%20'として表示されていました。スペースをアンダースコアに置き換えただけで、うまくいきました。

これは名前で最良の解決策ではありませんが、機能します。また、プログラムのワークフローを混乱させる可能性がある元のURIの一部にするために、ファイル名を使用可能にする必要があることも意味します。 PDFを生成するサーバー側の呼び出し中に現在生成またはデータベースから取得されている場合、フォーム送信の一部としてファイル名を生成するコードをJavaScriptに移動する必要があるか、データベースから取得した場合は結果としてインラインPDFになるURLを構築するときに、ファイル名を取得するためのクイックajax呼び出し。

フォーム上のユーザー入力からファイル名を取得する場合は、エスケープ文字が含まれていないことを検証する必要があります。これにより、ユーザーが煩わしくなります。

お役に立てば幸いです。

9
Troy Howard

他のパラメータの前に、URLの最後にファイル名を配置してください。これでうまくいきました。 http://www.setasign.de/support/tips-and-tricks/filename-in-browser-plugin/

5
tekkgurrl

Apacheのmod_rewriteはこれを解決できます。

/foo/getDoc.serviceにエンドポイントがあるWebサービスがあります。もちろん、AcrobatはファイルをgetDoc.pdfとして保存します。 Apache.confに次の行を追加しました:

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

これで/foo/getDoc/filename.pdf?bar&quxを要求すると、内部的に/foo/getDoc.service?bar&quxに書き換えられるため、Webサービスの正しいエンドポイントに到達しましたが、Acrobatはファイルをfilename.pdfとして保存すると認識します。

4
Mark Nettle

ASP.NET 2.0では、URLを

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

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

これはAcrobat 8​​で機能し、デフォルトのSaveAsファイル名はMySaveAsFileName.pdfになりました。

ただし、MySaveAsFileNameで使用できる文字を制限する必要があります(ピリオドなどは使用できません)。

4
Karsten

Asp.netを使用する場合、ページ(url)ファイル名を介してPDFファイル名を制御できます。他のユーザーが書いたように、Acrobatは少しだけ...「保存」ボタンを押してPDFファイル名を選択すると、ページ名を取得し、拡張子を削除して「.pdf」を追加します。したがって、/ foo/bar/GetMyPdf.aspxはGetMyPdf.pdfを提供します。

私が見つけた唯一の解決策は、asp.netハンドラーを介して「動的」ページ名を管理することです。

  • iHttpHandlerを実装するクラスを作成する
  • クラスにバインドされたweb.configのハンドラーをマップします

マッピング1:すべてのページに共通の基数(MyDocument_)があります。

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

Mapping2:完全に自由なファイル名(パスにフォルダーが必要):

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

ここでいくつかのヒント(pdfはiTextSharpを使用して動的に作成されます):
http://fhtino.blogspot.com/2006/11/how-to-show-or-download-pdf-file-from.html

2

添付ファイルの代わりにインラインで試すことができます:

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

Crystal Reports出力をPDFに生成する以前のWebアプリケーションでインラインを使用し、それをブラウザーでユーザーに送信しました。

1
ManiacZX

私はこれがすでにいくつかのフレーバーで言及されていると思いますが、私は自分の言葉でそれを述べようとします。

これよりも:

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

私はこれを使います:

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

「エクスポート」でリクエストを処理するのではなく、リクエストが届くと、GeneratePDF = 1のURLを調べます。見つかった場合、システムがPDFロケーションで/bar/sessions/958d8a22-0/views/1493881172/NameThatIWantPDFToBe.pdf。 URLにGeneratePDFが見つからない場合は、要求されたファイルを送信するだけです。 (要求されたファイルに単純にリダイレクトできないことに注意してください。そうしないと、無限ループに陥ってしまいます)

1
Matt

保存して開くオプションを備えたファイルダウンロードダイアログ(PDF)

覚えておくべきポイント:

  1. サービスから正しい配列サイズのストリームを返す
  2. ストリーム長に基づいて、正しいバイト長でストリームから到着したバイトを読み取ります。
  3. 正しいcontenttypeを設定する

これは、ストリームを読み取り、PDF fileのファイルダウンロードダイアログを開く

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

同じ問題があるので、ここにリダイレクトされました。トロイハワードの回避策も試しましたが、うまくいかないようです。

私がこれに対して行ったアプローチは、応答オブジェクトを使用せずにオンザフライでファイルを書き込むことです。 PDFはすでにサーバー上に存在するので、私が行ったのは、そのページを指すようにページをリダイレクトすることでしたPDFファイル。うまく動作します。

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

私の漠然とした説明があなたにアイデアを与えてくれれば幸いです。

0
mark

あなたは常に2つのリンクを持つことができます。 1つはブラウザー内でドキュメントを開き、もう1つはそれをダウンロードします(正しくないコンテンツタイプを使用)。これがGmailの機能です。

0
Vincent McNabb

まだこれを見ている人のために、私は見つかった解決策を使用しました here とそれは素晴らしく機能しました。ファブリツィオ、ありがとう!

0
Brian

私がこれを(PHPで)解決した方法は次のとおりです:

URLがSomeScript.php?id=ID&data=DATAで、使用するファイルがTEST.pdfだとします。

URLをSomeScript.php/id/ID/data/DATA/EXT/TEST.pdfに変更します。

最後のパラメーターは、アドビに使用させたいファイル名であることが重要です( 'EXT'は何でもかまいません)。上記の文字列にBTWという特殊文字がないことを確認してください。

次に、SomeScript.phpの上部に次を追加します。

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

次に、この関数をSomeScript.php(または関数ライブラリ)に追加します。

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

これで、$_REQUEST(または、必要に応じて$_GET)に通常の$_REQUEST['id']$_REQUEST['data']などのようにアクセスできるようになりました。

アドビでは、インラインで送信するときに、希望するファイル名をデフォルトの別名保存またはメール情報として使用します。

0
Rick Cooper

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

確認する

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

Firefox 62.0b5(64ビット):OK。

Chrome 67.0.3396.99(64ビット):OK。

IE 11:コメントはありません。

0
qräbnö