It's been a while since I've updated my blog. I've been quite busy lately, and just have not had the time that I used to. We're expecting our 1st child in just a few short weeks now, so most of my free time has been spent learning Lamaze breathing, making the weekly run to Babies R Us, and relocating my office from the larger room upstairs to the smaller one downstairs - which I do happen to like MUCH more than I had anticipated. I have everything I need within a short walk - a bathroom, beer fridge, and 52" HD TV. I only need to go upstairs to eat and sleep now, but alas, this will all change soon...
Recently, I was asked if you could change the way Export to CSV in ApEx works. The short answer is, of course, no. But it's not too difficult to "roll your own" CSV export procedure.
Why would you want to do this? Well, the customer's requirement was to manipulate some data when the Export link was clicked, and then export it to CSV in a format which can be imported into PeopleSoft. With the built-in export functionality, this is simply not possible.
It's almost too easy. Simply create a Report Region with your favorite query. Add a button or link or anything which will get you to a blank page. On that page, add a PL/SQL process which will fire "On Load - Before Header" In the source of that process, use this code:
You can download the export file here.
Recently, I was asked if you could change the way Export to CSV in ApEx works. The short answer is, of course, no. But it's not too difficult to "roll your own" CSV export procedure.
Why would you want to do this? Well, the customer's requirement was to manipulate some data when the Export link was clicked, and then export it to CSV in a format which can be imported into PeopleSoft. With the built-in export functionality, this is simply not possible.
It's almost too easy. Simply create a Report Region with your favorite query. Add a button or link or anything which will get you to a blank page. On that page, add a PL/SQL process which will fire "On Load - Before Header" In the source of that process, use this code:
begin
-- Set the MIME type
owa_util.mime_header( 'application/octet', FALSE );
-- Set the name of the file
htp.p('Content-Disposition: attachment; filename="emp.csv"');
-- Close the HTTP Header
owa_util.http_header_close;
-- Loop through all rows in EMP
for x in (select e.ename, e.empno, d.dname
from emp e, dept d where e.deptno = d.deptno
and e.deptno like :P1_DEPTNO)
loop
-- Print out a portion of a row,
-- separated by commas and ended by a CR
htp.prn(x.ename ||','|| x.empno ||','||
x.dname || chr(13));
end loop;
-- Send an error code so that the
-- rest of the HTML does not render
htmldb_application.g_unrecoverable_error := true;
end;
You can download the export file here.
Comments
I tried your export to CSV. Unfortunately the EMP.CSV file that was created has no data in it.
Thansk, Mike. I am so blissfully unaware of just how much change is coming. :)
I tried your export to CSV. Unfortunately the EMP.CSV file that was created has no data in it.
I fixed a small bug. It should be working now, and you can re-download the export file as well.
Thanks,
- Scott -
My heartiest congrats to you and entire family.
PS:Sir,I noticed that your website is using the syntax of APEX in the URL.Is your site is now using APEx as its base?Just curious so asked.
best regards and once again congrats a bunch.
aman
Thanks for your kind wishes!
PS:Sir,I noticed that your website is using the syntax of APEX in the URL.Is your site is now using APEx as its base?Just curious so asked.
Yes, you are correct. Sort of. I have 2 sites - sumnertech.com and sumnertechnologies.com. Currently, my static site is on sumnertech.com, and sumnertechnologies.com is a hosted site from Revion.com, which is running ApEx. My plan is to move everyting to ApEx, and merge the two sites, but it's been hard getting the time to do that.
Thanks,
- Scott -
thanx alot.You know I always wanted to ask you that why your site is not an APEX but a static one?Glad that very soon,we all shall see the full blown APEX site running.
with best regards
aman
Thanks and Regards
V
Thus, change this line:
htp.prn(x.ename ||','|| x.empno ||','|| x.dname || chr(13));
To this:
htp.prn('"' || x.ename ||'","'|| x.empno ||'","'|| x.dname || '"' || chr(13));
Thanks,
- Scott -
i have a question to the "custom export to csv"
how can a change your procedure in the way that I can said where the default place to save the file is
like C:\EXPORT_CSV\file_name.csv
is this possible
thanks for help
Off the top of my head, I don't think you can, as it's a setting of the specfic browser, not the server.
Thanks,
- Scott -
How can we do if we want to export multiple csv files by pressing a button or a link. My data is in views (arround 50 views). I want to create multiple csv files the name I can use same as view name. I appreciate your help.
Thanks,
James.
James - I'm not sure if this is possible, as once an HTTP stream is started & stopped, I'm not sure that you can easily - if at all - restart it.
Sorry that I don't have a better answer.
- Scott -
Used your code - worked ok. Is it possible to manipulate excel within html e.g. adjust column size, align it etc.
ImraneA
If you want to change the formatting, you'll probably have better luck with the OWA_SYLK Utility
Thanks,
- Scott -
your posts on this blog and advice on APEX forum are invaluable. Thanks for your time, it helps us novices greatly! I have a question that is not 100% related to a "Custom Export to CSV."
We have an APEX application with mail merge and document management system used by 200+ employees (and rapidly expanding). Mail merge has been setup by exporting CSV file to a PC, and opening mail merge document stored as a blob. Works perfect.
That is, until PCs with Office 2007 started rolling in. Word 2007 (and 2003) are not using DDL technology, and CSV and TXT files cen not be used without going through entire mail merge setup every time a template is open.
So, my question is two-fold. Have any of your existing customers experienced this? What was their solution?
Second - can APEX export any other file format except for CSV (XML comes to mind). If not, will future releases provide export format options?
I may cross-post this message in APEX forum, if a solution can be found. Thanks in advance for any insight.
Vojin
vjanjic457081@comcast.net
Thanks! Glad that you find it useful.
I may cross-post this message in APEX forum, if a solution can be found. Thanks in advance for any insight.
FYI - here is the OTN Forum link for this topic: http://forums.oracle.com/forums/thread.jspa?messageID=1648185
I have posted my comments there as well.
Thanks,
- Scott -
Vojin
I’m having difficulties. I keep getting an empty file. I’m using a multi-select list as a parameter on the report. I created a hidden item and called it P1_HID_UG. I’m using a computation on page 1 to format the multi-select list so it can be used in an IN clause. The format of the value in the hidden item is (‘2’,’22’,’7’,’5’). I have confirmed this displaying the session information on Page 1.
The code for the CSV export is:
BEGIN
-- Set the MIME type
owa_util.mime_header( 'application/octet', FALSE );
-- Set the name of the file
htp.p('Content-Disposition: attachment; filename="na_mail_list.csv"');
-- Close the HTTP Header
owa_util.http_header_close;
-- Loop through all rows
FOR x IN (SELECT DISTINCT d.agent_number, g.user_group||' - '||ug.description "User Group",
d.name, d.address1, d.address2, d.city,
d.state, d.zip_code
FROM naclhi_distribution d, naclhi_groups g, naclhi_user_group ug
WHERE d.agent_number = g.agent_number
AND g.user_group = ug.user_group
AND g.user_group IN :P1_HID_UG
ORDER BY 2)
LOOP
-- Print out a portion of a row,
-- separated by commas and ended by a CR
htp.prn('"'|| x."User Group" ||'","'
|| x.agent_number ||'","'
|| x.name ||'","'
|| x.address1 ||'","'
|| x.address2 ||'","'
|| x.city ||'","'
|| x.state ||'","'
|| x.zip_code ||'"'||
chr(13));
END LOOP;
-- Send an error code so that the
-- rest of the HTML does not render
htmldb_application.g_unrecoverable_error := true;
END;
Yes there is actually data based on that query.
Can you see or do you know why I keep getting an empty file?
Thank you,
Joe
AND g.user_group IN :P1_HID_UG
Thanks,
- Scott -
Yes it does. It also works if I hard code the IN clause.
Thanks,
Joe
Thanks,
- Scott -
'('||''''||REPLACE(:P1_USER_GROUP,':', ''''||','||'''')||''''||')'
Thanks,
Joe
You can e-mail the credentials to me directly at scott at sumnertech dot com.
Thanks,
- Scott -
An email was sent. I must also mention that I'm on version 2.0
Thank you very much!
Really its a superb solution to export report into CSV.
Regards
Chandru
Congratulations on your impending/recent family addition.
I have a number of 'PL/SQL function body returning SQL query' reports which I need to write some sort of custom csv export for. In order to implement your method it looks as though I need to know the report sql in order to write the custom export function; Is there any way I can write an entirely generic custom export function?
Cheers
Adam
Thank you.
http://deneskubicek.blogspot.com/2008/01/export-to-excel-1500-downloads.html
Thanks,
- Scott -
there are 3columns in my report EIN,OUC,EIN KEY and i want to export the report to excel.
But in excel i want only 2columns EIN,OUC to be shown when imported.
How can we do dis??
Thanks in advance
I'm not that familiar with Siebel; are you calling this procedure from a Siebel page, or from APEX?
- Scott -
Earlier (11/16/2006) there was a post regarding a need to export multiple CSV files when a button is pressed, and you stated:
"I'm not sure if this is possible, as once an HTTP stream is started & stopped, I'm not sure that you can easily - if at all - restart it.
Sorry that I don't have a better answer."
I find myself with the need to export multiple CSV files. I tried your sample a couple of different ways, and even tried putting each export into a separate process - to no avail.
Have you since found a way to export several files from the same button process?
Heck, even a button for each would work for me.
You can, however, easily have multiple buttons call different export procedures. If you create a button with a URL redirect to the page which contains the code in this blog post, you can pass in a Request parameter, and then make each process conditional based on the value of the Request parameter.
Thus, button A calls process A, button B calls process B, and so on.
Hope this helps!
- Scott -
I have used your code successfully for each of the exports I've created when each is run individually, and have tried all sorts of variations of repeating the code for 2 separate exports run at the same time (when I get that to work I will add the third).
I've tried with both exports in the same process; each export in its own process on the same page; and each export in its own process on two separate pages - one on the 'calling' page, the other in a separate page branched to via the Target Type 'Page in this Application'. All to no avail. Bummer.
In reading your response, I am wondering if it will work if I branch via a Target Type of 'URL'??? (Yes, that is a statement and a question rolled into one) If so, what is the difference between the two that would make the URL type work? Pretty much all of my branching is via 'Page in this Application'. When would one want to use 'URL'.
TIA,
Thomas
The only other approach that I can think of would be to ZIP up the CSV files and then download the actual ZIP. Joel Kallman blogged on how to ZIP files within the database here: http://joelkallman.blogspot.com/2008/04/zip-it.html
You'll need to get out your Java hat for that (and have it installed in the database), but it's very well documented and if you follow his steps, you should have little difficulty.
Thanks,
- Scott -
Fantastic, you should sell that code back to Oracle. Using the standard interactive report export download , my application was timing out (default 5 minute Apache timeout) before it produce the csv file. Now with that code you supplied it produces the file in around 30 seconds.
Regards
David
PS.
Now for the more difficult coding exercise - to make this generic so the for loop can take it's input from the proceding calling page.
I have an interactive report which returns more than 65,000 records.
While trying to export to an csv file ,it displays only 65000 records.Is there anyway to diaplay more than 65000 records?
Thanks and Regards,
Did you have any luck figuring out the solution to the issue with loss of leading zeros when exporting to Excel? I also have this issue and couldn't fix with double quoting the fields.
Thank you,
Michelle
First of all, is it possible to export data into an existing *xls worksheet using your attempt?
And is it also possible to specify the cell ranges for the exported values? For example starting at cell C4? Maybe you'll find the time to reply! Would be awesome!
Thanks,
Sebastian
Unfortunately, no and no are the answers to your questions. This solution exports to CSV, not XLS. Excel can read CSV, but there is nothing specific about the CSV format.
Thanks,
- Scott -
1 error has occurred
ORA-06550: line 3, column 1: PLS-00306: wrong number or types of arguments in call to 'MIME_HEADER' ORA-06550: line 3, column 1: PL/SQL: Statement ignored
I have an interactive report. I set a control break on one column, so APEX generates correctly more "sub-report".
I need to export into csv file every single "sub-report" separately.
Is it possible? Thank you very much,
Carlo.
This provided answers to a question I have been putting off for months.
Thanks again,
Greg
However I was wondering how you can add headings for csv columns (first line) in the same export csv file ?
Is this possible, and if yes, how can this be done ?
Thanks, Wim.
Just put another line before the LOOP that prints out the column headers. Something like this should work:
htp.prn('ENAME,EMPNO,DNAME' || chr(13));
Thanks,
- Scott -
I'm having a problem with the Export to CSV option. Whenever someone clicks on the link, he/she gets an Error 404.
Unable to understand why...??
Off late I have also seen that we get too many unexplained Error 404 from APEX.
So any idea why the export to CSV doesn't work?
Do I need to explicitly specify a delimiter in the report options??
Regards,
Arijit
Thanks a lot. It solved one of the issue mine where I was facing the problem of downloading huge (more than 1 lakh)records in csv format using the normal FLOW_EXCEL_OUTPUT... method.
Thanks,
- Scott -
https://forums.oracle.com/forums/thread.jspa?messageID=10719624
Thanks for your valuable post, I have a question when I am trying to export report that contains Arabic data it gives me unknown characters,I have tried the standard and yours methods,can you please advise on this?
Best regards
Mohannad
Thanks,
- Scott -
I had a requirement to add custom header row in a Export to Excel file in Apex.
Previously i successfully used your above code in 1 application which was in Apex version 4.1.0.00.32.
Recently i am facing problem to implement this in an application which have apex version 4.0.2.00.06. It is creating the .csv file and opening it in the browser instead of downloading it. Can you please help me out..
I am using the following code :-
begin
-- Set the MIME type
owa_util.mime_header( 'application/octet', FALSE );
-- Set the name of the file
htp.p('Content-Disposition: attachment; filename="emp.csv"');
-- Close the HTTP Header
owa_util.http_header_close;
htmldb_application.g_unrecoverable_error := true;
-- Loop through all rows in EMP
for x in (select e.ename, e.empno, d.dname
from emp e, dept d where e.deptno = d.deptno
)
loop
-- Print out a portion of a row,
-- separated by commas and ended by a CR
htp.prn(x.ename ||','|| x.empno ||','||
x.dname || chr(13));
end loop;
-- Send an error code so that the
-- rest of the HTML does not render
htmldb_application.g_unrecoverable_error := true;
end;
Or is there any other easy way to add 1 custom row when export to excel from apex?
Thanks
Subhojit
If you need a custom header row, simple write that before the start of the LOOP.
Not sure why APEX 4.0 is opening the file in the browser vs. downloading it. Typically this is a browser setting that you can set to determine how to handle a specific file type.
Thanks,
- Scott -
Is there any other way to add 1 custom row when export to excel from apex?
Thanks
Subhojit
This snipper will allow you to put an additional row at the top of a standard report:
SELECT
*
FROM
(
SELECT
TO_CHAR(empno) empno,
ename,
TO_CHAR(deptno) deptno,
1 id
FROM
emp
UNION
SELECT
'empno' empno,
'ename' ename,
'deptno' deptno,
0 id
FROM
dual
)
WHERE
1 = CASE
WHEN :REQUEST LIKE 'FLOW_EXCEL_OUTPUT%' AND id = 0 THEN 1
WHEN id = 1 THEN 1
END
ORDER BY
id
And this one will work for an Interactive Report (CSV only):
SELECT
*
FROM
(
SELECT
TO_CHAR(empno) empno,
ename,
TO_CHAR(deptno) deptno,
1 id
FROM
emp
UNION
SELECT
'empno' empno,
'ename' ename,
'deptno' deptno,
0 id
FROM
dual
)
WHERE
1 = CASE
WHEN :REQUEST LIKE 'CSV' AND id = 0 THEN 1
WHEN id = 1 THEN 1
END
ORDER BY
id
The issue here is that you'll have to convert all columns to VARCHARs, so that your custom row will be the same datatype as the data itself. You'll also want to set the ID column to not display when exported, as it serves no other purpose than to ensure that your custom row appears first.
Thanks,
- Scott -
Thanks for your suggestion. I successfully implemented that.
I have another apex classic report. I added custom column group header using jquery. Is there any way to include that column group header to export to excel.
Thanks
Subhojit
It's possible, but would likely require a custom export procedure.
- Scott -
Any ideas? We are serving over https, but I wouldn't think that's an issue.
Hope this helps.
- Scott -
You can use the bind variable syntax to refer to the value of the items: :P1_ITEM_NAME. However, they may not be set in session state. If that's the case, then you're better off using a Dynamic Action to first set them, and then call the export to CSV routine.
- Scott -
Can you export 2 routines in the same CSV file?
- Scott -
The example that I provide only outputs data; you'd have to add a line before the loop to output the headers.
- Scott -
Thank you for the post. It is very helpful. I have a requirement to export the report title and parameter values to the .csv file. Our queries are fairly complex. Some of them have over 60-70 columns and take about 20 mins to render the report itself. Is there a better way to export other than executing the query all over again? We are using version 5.1.3
- Scott -
Is it possible to show blob column in this export?
Am having employee image in my table stored as blob column. I want my csv with employee image too.
Please let me how to achieve this with this method.
Thanks,
Nivetha
- Scott -