We have an Oracle 10g application, built using Oracle PL/SQL Toolkits
and PSPs, using an Oracle database with an HTML front-end (hosted by
an Apache web server). We use the WPG_DOCLOAD package to upload and
download attachments to/from the database (i.e. Excel and Word files,
etc).
When the users download the documents back to their PC, internally we
call the method:
wpg_docload.download_file()
and they are then prompted to open or save the file. If they choose
save, the save dialog window appears but the name of the file is
pmp_file_download (the name of our oracle stored procedure that calls
the wpg_docload package) and is not the actual name of the file
itself.
Thus, the default behavior (for Save As) is a complex combination of
looking at the MIME type plus the name of the database object that
calls this method itself. We'd much rather pass a value like
"sample.xls" as the Save As filename instead.
Has anyone figured out a way around this problem? Of course, I've
looked at the package's source code - and there's no parameter I can
send to WPG_DOCLOAD to make this happen. If there is, perhaps you
could tell me?
Thank you!
Joe
Which version of wpg_docload.download_file() are you using? Table-
oriented or LOB-oriented? That is, one that accepts file name and
caching arguments or one that accepts single BLOB/BFILE argument? In
first case, mod_plsql should use the file name and MIME type from the
document table and you usually don't need to do anything special.
When sending a BLOB though you need to send a couple of extra headers
in the response: Content-Type, which will identify the MIME type of
the entity being sent, and Content-Disposition, which is not
officially standard, but is documented in RFC-2616 as de-facto
standard way to communicate the suggested file name to the client.
So your pmp_file_download procedure should look like this:
...
-- clear the output buffer and reset response state
htp.init;
-- suppress automatic HTTP header generation
htp.addDefaultHTMLHdr(False);
-- set Content-Type, don't close headers yet
owa_util.mime_header(v_content_type,False);
-- send Content-Disposition and suggest a file name for saving
htp.p('Content-Disposition: attachment; filename="'||v_filename||'"');
-- now close headers section
owa_util.http_header_close;
-- and send the file
wpg_docload.download_file(file);
...
Assuming that v_content_type is set to 'application/vnd.ms-excel' and
v_filename to 'sample.xls', most modern browsers will suggest
sample.xls when saving the output and correct program when opening it.
Alternatively, you could use path aliasing or automatic document path
functionality in your application. In short, your pmp_file_download
procedure would issue a redirect to the document path or path alias
appending desired file name to the path, and document procedure or
path alias procedure would resolve that file name, fetch or generate
corresponding content, and call wpg_docload.download_file(). Since the
filename is already on the URL, it will be suggested by the browser
automatically when saving, no need for extra quirky headers. See the
docs for details on PlsqlDocumentPath/PlsqlDocumentProcedure and
PlsqlPathAlias/PlsqlPathAliasProcedure and how they work.
And now a very simple solution that requires no RTFM and very little
implementation effort: create a package named SAMPLE and a procedure
named XLS in that package and call pmp_download_file from that
procecure instead. The URL will be something like myserver/dad/
sample.xls?arg1=this&arg2=that..., browsers will strip the query part
from it and will suggest to save the content into 'sample.xls', just
what you want. :)
Hth,
Vladimir M. Zakharychev
N-Networks, makers of Dynamic PSP(tm)
http://www.dynamicpsp.com