"名称"网络pdf更好地默认在Acrobat中保存文件名?
我的应用程序生成PDF供用户使用。如此处所述,设置" Content-Disposition" http标头。设置为" inline; filename = foo.pdf",对于Acrobat在保存pdf时提供" foo.pdf"作为文件名应该足够了。
但是,单击嵌入浏览器的Acrobat中的"保存"按钮时,要保存的默认名称不是该文件名,而是将带有斜杠的URL更改为下划线。巨大而丑陋。有没有办法影响Adobe中的默认文件名?
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验证)可悲的是,它们都没有起作用。
示例网址为
/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=433613)和IE中被打破,但可以在Opera,Safari和Chrome中使用。 http://greenbytes.de/tech/tc2231/#inlwithascii文件名pdf
解决方案
我们总是可以有两个链接。一种是在浏览器中打开文档,另一种是下载(使用错误的内容类型)。这就是Gmail的功能。
还要在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);
除了附件,我们还可以尝试内联:
Response.AddHeader("content-disposition", "inline;filename=MyFile.pdf");
我在以前的Web应用程序中使用了inline,该应用程序将Crystal Reports输出生成为PDF,并将其在浏览器中发送给用户。
像我们一样,我也尽力使它起作用。最后,我放弃了这个想法,只是选择了一种解决方法。
我正在使用ASP.NET MVC Framework,因此我修改了该控制器/操作的路由,以确保提供的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调用即可获取文件名。
如果要从表单上的用户输入中获取文件名,则应验证该文件名不包含转义字符,这会使用户烦恼。
希望能有所帮助。
我被重定向到这里,因为我有同样的问题。我也尝试了Troy Howard的解决方法,但似乎不起作用。
我对此所做的方法是,不再使用响应对象即时写入文件。由于PDF已经存在于服务器上,所以我要做的就是将页面重定向到该PDF文件。效果很好。
http://forums.asp.net/t/143631.aspx
我希望我模糊的解释能给我们一个主意。
问题的部分原因是相关的RFC 2183并未真正说明如何处理"内联"和文件名的处置类型。
而且,据我所知,唯一真正使用type = inline的文件名的UA是Firefox(请参阅测试用例)。
最后,插件API实际上是否可以使该信息可用并不明显(也许熟悉该API的男孩可以详细说明)。
话虽如此,我已经向Adobe的人发送了一个指向该问题的指导。也许合适的人会看一下。
相关信息:请参阅草稿-reschke-rfc2183-in-http中的尝试澄清HTTP中的Content-Disposition的尝试-这是正在进行的早期工作,反馈表示赞赏。
更新:我添加了一个测试用例,它似乎表明Acrobat reader插件虽然在API中提供了对它们的访问,但并未使用响应标头(在Firefox中)。
如果可执行文件是" get.cgi",请尝试此操作
http://server,org/get.cgi/filename.pdf?file = filename.pdf
是的,完全疯了。服务器上没有名为" filename.pdf"的文件,在可执行文件get.cgi下根本没有目录。
但这似乎可行。服务器忽略filename.pdf,而pdf阅读器忽略" get.cgi"
担
我相信已经以一种或者另一种方式提到了这一点,但我会尝试用我自己的话来陈述。
而不是这样:
/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中查找。如果找到,我将运行"导出"中运行的任何代码,而不是允许我的系统尝试在`/bar/sessions/958d8a22-0/views/1493881172/NameThatIWantPDFToBe.pdf"位置中搜索和提供PDF。如果在URL中未找到GeneratePDF,我只发送所请求的文件。 (请注意,我不能简单地重定向到所请求的文件,否则我将陷入无尽的循环)
如果使用asp.net,则可以通过页面(url)文件名来控制pdf文件名。
正如其他用户所写的那样,当我们按"保存"按钮时选择pdf文件名时,Acrobat有点...:它带有页面名称,删除扩展名并添加" .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"/>
这里有一些技巧(使用iTextSharp动态创建pdf):
http://fhtino.blogspot.com/2006/11/how-to-show-or-download-pdf-file-from.html
我(使用PHP)解决此问题的方法如下:
假设URL是SomeScript.php?id = ID&data = DATA
,而我们要使用的文件是TEST.pdf
。
将网址更改为" SomeScript.php / id / ID / data / DATA / EXT / TEST.pdf"。
重要的是,最后一个参数是要Adobe使用的文件名(" 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 ['id'],$ _ REQUEST ['data']等一样访问$ _REQUEST
(如果愿意,也可以使用$ _GET)。
内联发送时,Adobe将使用我们所需的文件名作为默认的另存为或者电子邮件信息。
对于仍在查看此内容的任何人,我都使用了此处找到的解决方案,并且效果很好。谢谢Fabrizio!
带有保存和打开选项的文件下载对话框(PDF)
要记住的要点:
- 从服务以正确的数组大小返回Stream
- 根据流长度,从具有正确字节长度的流中读取字节数组。
- 设置正确的内容类型
这是读取流的代码,并打开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(); } }
在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中允许的字符(无句点等)。