Quantcast
Channel: Comments on: Create an Excel-file with PL/SQL
Viewing all 73 articles
Browse latest View live

By: TonyReed

$
0
0

Finally a litle more time to experiment.

I have modified it to the following:
<workbookPr date1904=”false” dateCompatibility=”true” defaultThemeVersion=”124226″/>

Dates seem to be displaying correctly in Excel/win and Excel/Mac.

Dates are displaying as their decimal value in openOffice, but I can live with that, at least for now.


By: dieterdaniel

$
0
0

This package is really helpful!! Thanks for sharing it!
One question: would it be possible to open an existing XLS to edit data in there?

By: Anton Scheffer

$
0
0

@dieterdaniel
No, that’s not possible.

By: dieterdaniel

$
0
0

Understandable, it’s not the “native” Excel format that PL/SQL is working with.
I keep playing around with it. As I’m just starting out more examples would be aprecciated if other people already developed more “fancy” code to generate XLS sheets. Especially putting formulas or stuff like graphs into the results.

By: Anton Scheffer

$
0
0

@dieterdaniel
This package does produces the “native” xlsX Excel-format. But at the moment it can’t produce formulas, graphs or macro’s , just “data”

By: dieterdaniel

$
0
0

Anyhow this is a very good starting point and helps me a lot!! :-)

By: James Van Zandweghe

$
0
0

Hello,
Great package and functionality but i think i found a possible bug in the query2sheet function of the package.
In that function you have the t_sheet pls_integer variable.
you use that variable before a value is assigned to it.
Because of this you can’t specify what sheet you want to use for the results.
I think its better you put the following code at the beginning of your function
begin 
if p_sheet is null then
t_sheet := new_sheet;
else
t_sheet := nvl(p_sheet, workbook.sheets.count());
end if;
As you can see i also needed to overlead the new_sheet so that it returns the index of the new sheet.
 

By: Anton Scheffer

$
0
0

Moving the following line in the procedure a couple of lines up will do, no need for overloading new_sheet
t_sheet := nvl( p_sheet, workbook.sheets.count() );

So change it to:
if p_sheet is null
then
new_sheet;
end if;
t_sheet := nvl( p_sheet, workbook.sheets.count() );


By: James Van Zandweghe

$
0
0

I know.
We needed the overload function to get the index of a sheet so we can use that index in the other functions like cell.

By: Stefan Pastrilov

$
0
0

Hello,
Is it possible to generate xls file (Office 97-2003) ?
Regards,
Stefan Pastrilov

By: gilles

$
0
0

Hi Anton,
thanks a lot for this very usefull package.
I took time to add a personnal “Cursor2Sheet” procedure which works also on Oracle 10 (using XMLType in between

I Post it here incase it is of any use to anybody :

/************************************/
procedure cursor2sheet
( p_sql in sys_refcursor
, p_column_headers boolean := true
, p_directory varchar2 := null
, p_filename varchar2 := null
, p_sheet pls_integer := null
, p_footer boolean := true
)
is

ctx dbms_xmlgen.ctxHandle;
tmpXml XMLType ;

cursor cData is
Select
t2.Column_Value.GetRootElement() ColName
, ExtractValue(t2.Column_Value, ‘node()’) Value
From Table(XMLSequence(tmpXml)) t
, Table(XMLSequence(Extract(t.Column_Value,’/ROWSET/ROW/node()’))) t2
Order by RowNum ;

tsColHeaders SYS.DBMS_DEBUG_VC2COLL := SYS.DBMS_DEBUG_VC2COLL();
tsValues SYS.DBMS_DEBUG_VC2COLL := SYS.DBMS_DEBUG_VC2COLL();
t_sheet pls_integer := 1;
t_cur_row pls_integer := 1;
colId pls_integer := 1;
nColNumber pls_integer;
n pls_integer;

aTmpVal SYS.AnyData ;
nNumVal Number ;
tTSVal TimeStamp ;
dDateVal Date ;
sVarcharVal Varchar2(4000) ;
bGotType boolean ;
eTypeConvert Exception ;
eTypeDateFormat Exception ;
eTypeNonNumeric Exception ;
eTypeNotDefined Exception ;
pragma exception_init(eTypeConvert,-6502);
pragma exception_init(eTypeDateFormat,-1830);
pragma exception_init(eTypeNonNumeric,-1858);

begin

— XML Creation from the sys_refcursor
ctx := dbms_xmlgen.newContext(p_sql);
— this is important in order to get all the column headers, even if all data are null
dbms_xmlgen.SetNullHandling(ctx, dbms_xmlgen.EMPTY_TAG);
dbms_xmlgen.getXMLType(ctx, TmpXml);

if p_sheet is null
then
new_sheet;
end if;

— Load Columns and Values into Arrays
Open cData ;
Fetch cData bulk collect into tsColHeaders, tsValues ;
Close cData ;

— get distinct headers
tsColHeaders := set(tsColHeaders) ;
— get number of headers (of columns)
nColNumber := tsColHeaders.count ;

— Create column headers if wanted
If p_column_headers
Then

— set headers into sheet
For i in tsColHeaders.first .. tsColHeaders.last
Loop
cell(i, t_cur_row, tsColHeaders(i), p_fontId => get_font(‘Calibri’, p_bold => true), p_sheet => t_sheet);
End Loop ;
t_cur_row := 2;

End if;

t_sheet := nvl(p_sheet, workbook.sheets.count());

— fill cells
For i in tsValues.first .. tsValues.last
Loop
— check if we must reset col to 1 and go to next line
If i > nColNumber
and mod(i ,nColNumber) = 1
Then
— reset colId to 1 and go to next line
colId := 1 ;
t_cur_row := t_cur_row + 1;
End If ;

— find the good type and insert into Cell
— initialize “checker”
bGotType := false ;

— Number ?
If Not bGotType
Then
Begin
aTmpVal := Sys.AnyData.ConvertNumber(tsValues(i)) ;
bGotType := true ;
n := aTmpVal.GetNumber(nNumVal) ;
— load data into cell
cell(colId, t_cur_row, nNumVal, p_sheet => t_sheet ) ;

— if conversion fails
Exception
When eTypeConvert or eTypeDateFormat or eTypeNonNumeric
Then
bGotType := false ;

End ;
End If ;

— TimeStamp ?
If Not bGotType
Then
Begin
aTmpVal := Sys.AnyData.ConvertTimestamp(tsValues(i)) ;
bGotType := true ;
n := aTmpVal.GetTimeStamp(tTSVal) ;
— load data into cell
cell(colId, t_cur_row, to_date(tTSVal), p_sheet => t_sheet ) ;

— if conversion fails
Exception
When eTypeConvert or eTypeDateFormat or eTypeNonNumeric
Then
bGotType := false ;

End ;
End If ;

— Date ?
If Not bGotType
Then
Begin
aTmpVal := Sys.AnyData.ConvertDate(tsValues(i)) ;
bGotType := true ;
n := aTmpVal.GetDate(dDateVal) ;
— load data into cell
cell(colId, t_cur_row, dDateVal, p_sheet => t_sheet ) ;

— if conversion fails
Exception
When eTypeConvert or eTypeDateFormat or eTypeNonNumeric
Then
bGotType := false ;

End ;
End If ;

— Varchar2 ?
If Not bGotType
Then
Begin
aTmpVal := Sys.AnyData.ConvertVarchar2(tsValues(i)) ;
bGotType := true ;
n := aTmpVal.GetVarchar2(sVarcharVal) ;
— load data into cell
cell(colId, t_cur_row, sVarcharVal, p_sheet => t_sheet ) ;

— if conversion fails
Exception
When eTypeConvert or eTypeDateFormat or eTypeNonNumeric
Then
bGotType := false ;

End ;
End If ;

— unsupported type
If Not bGotType
Then
raise eTypeNotDefined ;
End If ;

— go to next col
colId := colId + 1 ;

End Loop ;

If p_footer
Then
— set footer
cell(1, t_cur_row+2 , ‘Generated ‘||sysdate||’ by ‘||user, p_sheet => t_sheet ) ;
End If ;

if ( p_directory is not null and p_filename is not null )
then
save( p_directory, p_filename );
end if;

exception
when eTypeNotDefined
then
raise_application_error(-20999,’one data has an unsupported type’, false);
raise;
when others
then
raise_application_error(-20999,’Export to XLSX failed’, true);

end;

By: Robyn Dyke

$
0
0

Hello,
I have the need to add excel formulas to the spreadsheet so that the user can see record counts in the spreadsheet following filtering applied by user post spreadsheet creation.

Has anyone experimented with adding excel formulas? perhaps have a plsql function already created to add this?

Thanks, Robyn

By: Btissam

$
0
0

Hi ,
When i tried to install the package it seems that something is missed (package, library..) .For example : “get_font invalid identifier ” or “new_sheet invalid identifier”…

Can you help in order to compile this very usefull package?

Many thanks

By: Anton Scheffer

$
0
0

@Btissam The source consists pf one package specification and one packakage body. If you run them unaltered they should compile OK

By: gilles

$
0
0

Hi Robyn
The code I have put into my Post is just an additional procedure to the original package…
did you download and compile the package from this site first ?

once done you can add my procedure to the newly created package.

Regards,
Gilles


By: medan

$
0
0

Hello Anton.

Thank you! It works well.

By: Mike Chambers

$
0
0

Robyn,

I have added formulas to my cells. Here are the changes I’ve applied:

Forgive me if there is a better way to post my changes. This is my first time posting code changes.

Mike Chambers

———————————–
—- package changes start
———————————–
procedure cell
( p_col pls_integer
, p_row pls_integer
, p_value number
, p_numFmtId pls_integer := null
, p_fontId pls_integer := null
, p_fillId pls_integer := null
, p_borderId pls_integer := null
, p_alignment tp_alignment := null
, p_sheet pls_integer := null
, p_type varchar2 default ‘v’ — if = ‘f’ then add p_formula to cell
, p_formula varchar2 default null — cell formula
);

procedure cell
( p_col pls_integer
, p_row pls_integer
, p_value varchar2
, p_numFmtId pls_integer := null
, p_fontId pls_integer := null
, p_fillId pls_integer := null
, p_borderId pls_integer := null
, p_alignment tp_alignment := null
, p_sheet pls_integer := null
, p_type varchar2 default ‘v’ — added M.CHAMBERS: if = ‘f’ then add p_formula to cell
, p_formula varchar2 default null –added M.CHAMBERS: cell formula
);

procedure cell
( p_col pls_integer
, p_row pls_integer
, p_value date
, p_numFmtId pls_integer := null
, p_fontId pls_integer := null
, p_fillId pls_integer := null
, p_borderId pls_integer := null
, p_alignment tp_alignment := null
, p_sheet pls_integer := null
, p_type varchar2 default ‘v’ — if = ‘f’ then add p_formula to cell
, p_formula varchar2 default null — cell formula
);

———————————–
—- package changes end
———————————–

———————————–
—- package body changes start
———————————–
–M.CHAMBERS: modified to_cell to add formula functionality
type tp_cell is record
( value number
, style varchar2(50)
, type varchar2(1) default ‘v’ –added M.CHAMBERS
, formula varchar2(1000) default null –added M.CHAMBERS
);

–M.CHAMBERS: modified to remove case sensitive issue for date format
function get_numFmt( p_format varchar2 := null )
return pls_integer
is
t_cnt pls_integer;
t_numFmtId pls_integer;
t_format varchar2(100) default lower(p_format); –added M.CHAMBERS
begin
if t_format is null –M.CHAMBERS: changed from p_format
then
return 0;
end if;
t_cnt := workbook.numFmts.count();
for i in 1 .. t_cnt
loop
if workbook.numFmts( i ).formatCode = t_format –M.CHAMBERS: changed from p_format
then
t_numFmtId := workbook.numFmts( i ).numFmtId;
exit;
end if;
end loop;
if t_numFmtId is null
then
t_numFmtId := case when t_cnt = 0 then 164 else workbook.numFmts( t_cnt ).numFmtId + 1 end;
t_cnt := t_cnt + 1;
workbook.numFmts( t_cnt ).numFmtId := t_numFmtId;
workbook.numFmts( t_cnt ).formatCode := t_format; –M.CHAMBERS: changed from p_format
workbook.numFmtIndexes( t_numFmtId ) := t_cnt;
end if;
return t_numFmtId;
end;

–M.CHAMBERS: modified to add formula functionality
procedure cell
( p_col pls_integer
, p_row pls_integer
, p_value number
, p_numFmtId pls_integer := null
, p_fontId pls_integer := null
, p_fillId pls_integer := null
, p_borderId pls_integer := null
, p_alignment tp_alignment := null
, p_sheet pls_integer := null
, p_type varchar2 default ‘v’ –added M.CHAMBERS
, p_formula varchar2 default null –added M.CHAMBERS
)
is
t_sheet pls_integer := nvl( p_sheet, workbook.sheets.count() );
begin
workbook.sheets( t_sheet ).rows( p_row )( p_col ).formula := p_formula; –added M.CHAMBERS
workbook.sheets( t_sheet ).rows( p_row )( p_col ).value := p_value ;
workbook.sheets( t_sheet ).rows( p_row )( p_col ).type := p_type; –added M.CHAMBERS
workbook.sheets( t_sheet ).rows( p_row )( p_col ).style := null;
workbook.sheets( t_sheet ).rows( p_row )( p_col ).style := get_XfId( t_sheet, p_col, p_row, p_numFmtId, p_fontId, p_fillId, p_borderId, p_alignment );
end;

–M.CHAMBERS: modified to add formula functionality
procedure cell
( p_col pls_integer
, p_row pls_integer
, p_value varchar2
, p_numFmtId pls_integer := null
, p_fontId pls_integer := null
, p_fillId pls_integer := null
, p_borderId pls_integer := null
, p_alignment tp_alignment := null
, p_sheet pls_integer := null
, p_type varchar2 default ‘v’ –added M.CHAMBERS
, p_formula varchar2 default null –added M.CHAMBERS
)
is
t_sheet pls_integer := nvl( p_sheet, workbook.sheets.count() );
t_alignment tp_alignment := p_alignment;
begin
workbook.sheets( t_sheet ).rows( p_row )( p_col ).formula := p_formula; –added M.CHAMBERS
workbook.sheets( t_sheet ).rows( p_row )( p_col ).value := add_string( p_value );
workbook.sheets( t_sheet ).rows( p_row )( p_col ).type := p_type; –added M.CHAMBERS
if t_alignment.wrapText is null and instr( p_value, chr(13) ) > 0
then
t_alignment.wrapText := true;
end if;
workbook.sheets( t_sheet ).rows( p_row )( p_col ).style := ‘t=”s” ‘ || get_XfId( t_sheet, p_col, p_row, p_numFmtId, p_fontId, p_fillId, p_borderId, t_alignment );
end;

–M.CHAMBERS: modified to add formula functionality
procedure cell
( p_col pls_integer
, p_row pls_integer
, p_value date
, p_numFmtId pls_integer := null
, p_fontId pls_integer := null
, p_fillId pls_integer := null
, p_borderId pls_integer := null
, p_alignment tp_alignment := null
, p_sheet pls_integer := null
, p_type varchar2 default ‘v’
, p_formula varchar2 default null
)
is
t_numFmtId pls_integer := p_numFmtId;
t_sheet pls_integer := nvl( p_sheet, workbook.sheets.count() );
begin
workbook.sheets( t_sheet ).rows( p_row )( p_col ).formula := p_formula; –added M.CHAMBERS
workbook.sheets( t_sheet ).rows( p_row )( p_col ).value := p_value – to_date(’01-01-1904′,’DD-MM-YYYY’);
workbook.sheets( t_sheet ).rows( p_row )( p_col ).type := p_type; –added M.CHAMBERS
if t_numFmtId is null
and not ( workbook.sheets( t_sheet ).col_fmts.exists( p_col )
and workbook.sheets( t_sheet ).col_fmts( p_col ).numFmtId is not null
)
and not ( workbook.sheets( t_sheet ).row_fmts.exists( p_row )
and workbook.sheets( t_sheet ).row_fmts( p_row ).numFmtId is not null
)
then
t_numFmtId := get_numFmt( ‘dd/mm/yyyy’ );
end if;
workbook.sheets( t_sheet ).rows( p_row )( p_col ).style := get_XfId( t_sheet, p_col, p_row, t_numFmtId, p_fontId, p_fillId, p_borderId, p_alignment );
end;

–changes to function finish: loop through cells. Modified t_cell := statment to include tag for forumla
while t_col_ind is not null
loop
t_cell := ”;

if workbook.sheets( s ).rows( t_row_ind )( t_col_ind ).type = ‘f’ then
t_cell := t_cell||”
|| workbook.sheets( s ).rows( t_row_ind )( t_col_ind ).formula
|| ”;
end if;
t_cell := t_cell||”
|| to_char( workbook.sheets( s ).rows( t_row_ind )( t_col_ind ).value, ‘TM9′, ‘NLS_NUMERIC_CHARACTERS=.,’ )
|| ”;
if t_len > 32000
then
dbms_lob.writeappend( t_xxx, t_len, t_tmp );
t_tmp := null;
t_len := 0;
end if;
t_tmp := t_tmp || t_cell;
t_len := t_len + length( t_cell );
t_col_ind := workbook.sheets( s ).rows( t_row_ind ).next( t_col_ind );
end loop;
t_tmp := t_tmp || ”;
t_row_ind := workbook.sheets( s ).rows.next( t_row_ind );
end loop;

By: Mike Chambers

$
0
0

Anton – this is is a wonderful package. Thank you very much for sharing this with everyone.

I have run into an issue that I wonder if anyone has resolved. After downloading the Excel file, I am unable to create formulas in cells that have text data. When I enter the formula such as =C2, the result is a text entry of =C2 rather than the value of C2.

Thank you,

Mike Chambers

By: euelvis

$
0
0

Mike,

You can try something like this in your code:
Worked for me in XE 10g(not tested for complex formulas or different return type).
I hope is useful.

—————————————————————————
/*
–Simple test calls:
as_xlsx.cell(1,1,”,p_type => ‘f’, p_formula => ‘B1+C1′ );
or
as_xlsx.cell(1,1,”,p_type => ‘f’, p_formula => ‘SUM(B1:C1)’ );
*/
—————————————————————————

while t_col_ind is not null
loop
/*Start 14-sep-2013*/
IF workbook.sheets(s).rows(t_row_ind)(t_col_ind).type = ‘f’ THEN
/*
SUM(B1:C1)
10
*/
declare
l_type varchar2(30):=’t=”array”‘;
begin
t_cell := ”
|| ”
|| workbook.sheets(s).rows(t_row_ind)(t_col_ind).formula
|| ”
/* || ”
|| to_char( workbook.sheets( s ).rows( t_row_ind )( t_col_ind ).value, ‘TM9′, ‘NLS_NUMERIC_CHARACTERS=.,’ )
|| ”*/
|| ”;
end;
else
/* End 14-sep-2013 */
t_cell := ”
|| to_char( workbook.sheets( s ).rows( t_row_ind )( t_col_ind ).value, ‘TM9′, ‘NLS_NUMERIC_CHARACTERS=.,’ )
|| ”;
END IF; /* 14-sep-2013 */

if t_len > 32000
then
dbms_lob.writeappend( t_xxx, t_len, t_tmp );
t_tmp := null;
t_len := 0;
end if;
t_tmp := t_tmp || t_cell;
t_len := t_len + length( t_cell );
t_col_ind := workbook.sheets( s ).rows( t_row_ind ).next( t_col_ind );
end loop;

—————————————————————————

instead of :

—————————————————————————

–changes to function finish: loop through cells. Modified t_cell := statment to include tag for forumla
while t_col_ind is not null
loop
t_cell := ”;

if workbook.sheets( s ).rows( t_row_ind )( t_col_ind ).type = ‘f’ then
t_cell := t_cell||”
|| workbook.sheets( s ).rows( t_row_ind )( t_col_ind ).formula
|| ”;
end if;
t_cell := t_cell||”
|| to_char( workbook.sheets( s ).rows( t_row_ind )( t_col_ind ).value, ‘TM9′, ‘NLS_NUMERIC_CHARACTERS=.,’ )
|| ”;
if t_len > 32000
then
dbms_lob.writeappend( t_xxx, t_len, t_tmp );
t_tmp := null;
t_len := 0;
end if;
t_tmp := t_tmp || t_cell;
t_len := t_len + length( t_cell );
t_col_ind := workbook.sheets( s ).rows( t_row_ind ).next( t_col_ind );
end loop;
t_tmp := t_tmp || ”;
t_row_ind := workbook.sheets( s ).rows.next( t_row_ind );
end loop;
—————————————————————————

Nice job Anton.

Best regards,

euelvis

By: euelvis

Viewing all 73 articles
Browse latest View live