2008-09-29 90 views
40

我的应用程序为用户消费生成PDF。 “Content-Disposition”http头部被设置为如提到的here。这被设置为“inline; filename = foo.pdf”,这对于Acrobat在保存pdf时给出“foo.pdf”作为文件名就足够了。“name”web pdf更好的默认保存文件名在Acrobat中?

但是,在浏览器嵌入的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的验证)可悲的是,既不工作。

示例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名:朱利安雷什克带来实际的洞察力和严谨的这种情况。请提出他的答案。 这似乎在FF(https://bugzilla.mozilla.org/show_bug.cgi?id=433613)和IE中被打破,但在Opera,Safari和Chrome中可用。 http://greenbytes.de/tech/tc2231/#inlwithasciifilenamepdf

回答

10

部分问题是,相关RFC 2183并未真正说明如何处理“内联”和文件名的处置类型。

另外,据我所知,实际使用type = inline的文件名的唯一UA是Firefox(请参阅test case)。

最后,插件API实际上使这些信息可用(可能某些熟悉API的人可以详细说明)并不明显。

这就是说,我已经发送了一个指向这个问题的指针给一个Adobe人;也许正确的人会看看。

相关:请参阅尝试澄清HTTP中的内容处置draft-reschke-rfc2183-in-http - 这是早期工作正在进行中,反馈赞赏。

更新:我添加了一个test case,这似乎表明Acrobat reader插件不使用响应标头(在Firefox中),尽管插件API提供了对它们的访问。

0

您可以始终有两个链接。一个在浏览器中打开文档,另一个下载它(使用不正确的内容类型)。这是Gmail所做的。

+0

对不起,但我相信这会比无所事事更糟糕(关于用户体验)。重命名文件并不是什么大事,只是一个令人讨厌的文件而已。 – 2008-09-29 23:42:38

+0

够公平的。 Gmail使用图片进行处理,我非常喜欢它。无论如何祝你好运:-) – 2008-09-30 00:00:03

7

设置文件名ContentType以及。这应该可以解决问题。

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

在设置内容处置头,还添加内容长度的头,然后使用的BinaryWrite流式传输的PDF。

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

他已经做到了。 Acrobat Reader忽略它,或者看起来如此。 – 2008-09-30 01:52:56

+1

建议设置ContentType =“application/pdf; name = foo.pdf”,他没有说他试过了。 – Vivek 2008-09-30 02:35:26

+0

我寄予厚望,但这似乎并不影响IE或FF中的Acrobat Reader 8.0。问题已更新。 – 2008-09-30 18:17:46

1

相反附件,你可以尝试在线:

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

我使用内嵌在生成的水晶报表输出成PDF以前的Web应用程序,并派出在浏览器的用户。

9

和你一样,我尝试着试着让这个工作。最后,我放弃了这个想法,并选择了一种解决方法。

我正在使用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

产生的头看起来就像你所描述的内容(内容类型为应用程序/ pdf,配置是内联的,文件名是头部无用的一部分)。 Acrobat在浏览器窗口中显示它(不保存为对话框),如果用户点击Acrobat保存按钮,自动填充的文件名就是报告文件名。

几个方面的考虑:

为了使文件名看起来体面,他们不应该有任何转义字符(例如,没有空格等)......这是一个有点限制。我的文件名在这种情况下是自动生成的,之前在它们中有空格,在结果保存对话框文件名中显示为'%20'。我只是用下划线替换空格,然后解决了。

这是没有名称的最佳解决方案,但它确实有效。这也意味着你必须有文件名才能使它成为原始URI的一部分,这可能会混淆你程序的工作流程。如果它在生成PDF的服务器端调用期间正在生成或从数据库中检索,那么可能需要将生成文件名的代码作为表单提交的一部分移至javascript,或者如果它来自数据库,则使其成为快速ajax调用来获取文件名时,建立URL导致内置的PDF。

如果您从表单上的用户输入中获取文件名,那么应该验证其不包含转义字符,这会惹恼用户。

希望有所帮助。

0

我在这里被重定向,因为我有同样的问题。我也试过特洛伊霍华德的解决方法,但它似乎并没有工作。

我在这一方面做的方法是不再使用响应对象来即时编写文件。由于PDF已经存在于服务器上,我所做的是将我的页面重定向到该PDF文件。很棒。

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

我希望我的解释含糊不清给你的想法。

-1

试试这个,如果你的可执行文件是 “get.cgi”

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

是的,这是完全疯了。在服务器上没有名为“filename.pdf”的文件,在可执行文件get.cgi下面都有目录。

但它似乎工作。服务器忽略filename.pdf和PDF阅读器忽略“get.cgi”

1

我相信这已经在一个味提及或其他,但我会尽力,并说明它在我自己话。

而不是这样的:

/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。如果找到,我会运行“导出”中运行的任何代码,而不允许我的系统尝试在地址/bar/sessions/958d8a22-0/views/1493881172/NameThatIWantPDFToBe.pdf中搜索并提供PDF。如果在URL中找不到GeneratePDF,我只需传输请求的文件。 (请注意,我不能简单地重定向到所请求的文件 - 否则我最终会陷入无限循环)

2

如果使用asp.net,则可以通过页面(url)文件名控制pdf文件名。 正如其他用户写的,Acrobat有点s ...当你按下“保存”按钮时选择pdf文件名称:它采用页面名称,删除扩展名并添加“.pdf”。 所以/foo/bar/GetMyPdf.aspx给GetMyPdf.pdf。

我发现的唯一的解决方案是通过一个asp.net处理程序管理“动态”页面名称:

  • 创建一个实现IHttpHandler的
  • 映射网络的处理程序类。配置界,类

Mapping1:所有页面都有一个共同的基数(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

0

我用PHP解决这个问题的方法如下:

假设你的URL是SomeScript.php?id=ID&data=DATA,你要使用的文件是TEST.pdf

将URL更改为SomeScript.php/id/ID/data/DATA/EXT/TEST.pdf

重要的是最后一个参数是您希望Adobe使用的文件名(“EXT”可以是任何内容)。确保在上面的字符串中没有特殊字符,顺便说一句。

现在,在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']

And Ado当您以内嵌方式发送时,请使用您想要的文件名作为默认保存或电子邮件信息。

0

对于任何人仍然在看这个,我使用的解决方案发现here,它的工作非常好。谢谢Fabrizio!

1

文件下载对话框(PDF)与保存和打开选项

点要记住:

  1. 返回物流与服务
  2. 正确的数组大小从正确的字节长度流读取的字节arrary根据流长度。
  3. 一套正确的contentType

下面是读取数据流的代码,并打开文件下载对话框的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

在ASP.NET 2.0中的变化从

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

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

这适用于Acrobat 8​​,默认的SaveAs文件名现在是​​。

但是,您必须限制在MySaveAsFileName(无句点等)中允许的字符。

4

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

相关问题