The SAS Output Delivery System and reporting techniques

ODS for pdf report

Accepted Solution Solved
Reply
Contributor
Posts: 66
Accepted Solution

ODS for pdf report

I have a code and got the report.

For the first figure I used 'ods pdf file=XXX ' to output. For the second figure, I got from listing output. You can see the formats of two figures are completely different.

I want to get the second figure with "ods pdf file=" . My question is how I can reach it.

 

My second question is when I use the fllowing code:

 

footnote1 "Created by %sysfunc(getoption(sysin)) on" " &sysdate9..";

 

the %sysfunc(getoption(sysin)) does not work.  

 

 

1.jpg2.jpg


Accepted Solutions
Solution
‎10-03-2016 09:13 AM
Trusted Advisor
Posts: 1,392

Re: ODS for pdf report

Please display your code, of both reports, to better understanding of your question.

View solution in original post


All Replies
Solution
‎10-03-2016 09:13 AM
Trusted Advisor
Posts: 1,392

Re: ODS for pdf report

Please display your code, of both reports, to better understanding of your question.

Contributor
Posts: 66

Re: ODS for pdf report

data demog;
label subjid = "Subject Number"
trt = "Treatment"
gender = "Gender"
race = "Race"
age = "Age";
input subjid trt gender race age @@;
datalines;
101 0 1 3 37 301 0 1 1 70 501 0 1 2 33 601 0 1 1 50 701 1 1 1 60
102 1 2 1 65 302 0 1 2 55 502 1 2 1 44 602 0 2 2 30 702 0 1 1 28
103 1 1 2 32 303 1 1 1 65 503 1 1 1 64 603 1 2 1 33 703 1 1 2 44
104 0 2 1 23 304 0 1 1 45 504 0 1 3 56 604 0 1 1 65 704 0 2 1 66
105 1 1 3 44 305 1 1 1 36 505 1 1 2 73 605 1 2 1 57 705 1 1 2 46
106 0 2 1 49 306 0 1 2 46 506 0 1 1 46 606 0 1 2 56 706 1 1 1 75
201 1 1 3 35 401 1 2 1 44 507 1 1 2 44 607 1 1 1 67 707 1 1 1 46
202 0 2 1 50 402 0 2 2 77 508 0 2 1 53 608 0 2 2 46 708 0 2 1 55
203 1 1 2 49 403 1 1 1 45 509 0 1 1 45 609 1 2 1 72 709 0 2 2 57
204 0 2 1 60 404 1 1 1 59 510 0 1 3 65 610 0 1 1 29 710 0 1 1 63
205 1 1 3 39 405 0 2 1 49 511 1 2 2 43 611 1 2 1 65 711 1 1 2 61
206 1 2 1 67 406 1 1 2 33 512 1 1 1 39 612 1 1 2 46 712 0 . 1 49
;
run;
**** CREATE FORMATS NEEDED FOR TABLE ROWS.;
proc format;
value gender
1 = "Male"
2 = "Female";
value race
1 = "White"
2 = "Black"
3 = "Other*";
run;
**** DUPLICATE THE INCOMING DATA SET FOR OVERALL COLUMN
**** CALCULATIONS SO NOW TRT HAS VALUES 0 = PLACEBO, 1 = ACTIVE,
**** AND 2 = OVERALL.;
data demog;
set demog;
output;
trt = 2;
output;
run;
**** AGE STATISTICS PROGRAMMING ********************************;
**** GET P VALUE FROM NON PARAMETRIC COMPARISON OF AGE MEANS.;
proc npar1way
data = demog
wilcoxon
noprint;
where trt in (0,1);
class trt;
var age;
output out = pvalue wilcoxon;
run;
proc sort
data = demog;
by trt;
run;
***** GET AGE DESCRIPTIVE STATISTICS N, MEAN, STD, MIN, AND MAX.;
proc univariate
data = demog noprint;
by trt;
var age;
output out = age
n = _n mean = _mean std = _std min = _min
max = _max;
run;
**** FORMAT AGE DESCRIPTIVE STATISTICS FOR THE TABLE.;
data age;
set age;
format n mean sd min max $14.;
drop _n _mean _std _min _max;
n = put(_n,3.);
mean = put(_mean,7.1);
std = put(_std,8.2);
min = put(_min,7.1);
max = put(_max,7.1);
run;
**** TRANSPOSE AGE DESCRIPTIVE STATISTICS INTO COLUMNS.;
proc transpose
data = age
out = age
prefix = col;
var n mean std min max;
id trt;
run;
**** CREATE AGE FIRST ROW FOR THE TABLE.;
data label;
set pvalue(keep = p2_wil rename = (p2_wil = pvalue));
length label $ 85;
label = "Age (years)";
run;
**** APPEND AGE DESCRIPTIVE STATISTICS TO AGE P VALUE ROW AND
**** CREATE AGE DESCRIPTIVE STATISTIC ROW LABELS.;
data age;
length label $ 85 col0 col1 col2 $ 25 ;
set label age;
keep label col0 col1 col2 pvalue ;
if _n_ > 1 then
select;
when(_NAME_ = 'n') label = " N";
when(_NAME_ = 'mean') label = " Mean";
when(_NAME_ = 'std') label = " Standard Deviation";
when(_NAME_ = 'min') label = " Minimum";
when(_NAME_ = 'max') label = " Maximum";
otherwise;
end;
run;
**** END OF AGE STATISTICS PROGRAMMING *************************;
**** GENDER STATISTICS PROGRAMMING *****************************;
**** GET SIMPLE FREQUENCY COUNTS FOR GENDER.;
proc freq
data = demog
noprint;
where trt ne .;
tables trt * gender / missing outpct out = gender;
run;
**** FORMAT GENDER N(%) AS DESIRED.;
data gender;
set gender;
where gender ne .;
length value $25;
value = put(count,4.) || ' (' || put(pct_row,5.1)||'%)';
run;
proc sort
data = gender;
by gender;
run;
**** TRANSPOSE THE GENDER SUMMARY STATISTICS.;
proc transpose
data = gender
out = gender(drop = _name_)
prefix = col;
by gender;
var value;
id trt;
run;
**** PERFORM CHI-SQUARE ON GENDER COMPARING ACTIVE VS PLACEBO.;
proc freq
data = demog
noprint;
where gender ne . and trt not in (.,2);
table gender * trt / chisq;
output out = pvalue pchi;
run;
**** CREATE GENDER FIRST ROW FOR THE TABLE.;
data label;
set pvalue(keep = p_pchi rename = (p_pchi = pvalue));
length label $ 85;
label = "Gender";
run;
**** APPEND GENDER DESCRIPTIVE STATISTICS TO GENDER P VALUE ROW
**** AND CREATE GENDER DESCRIPTIVE STATISTIC ROW LABELS.;
data gender;
length label $ 85 col0 col1 col2 $ 25 ;
set label gender;
keep label col0 col1 col2 pvalue ;
if _n_ > 1 then
label= " " || put(gender,gender.);
run;
**** END OF GENDER STATISTICS PROGRAMMING **********************;
**** RACE STATISTICS PROGRAMMING *******************************;
**** GET SIMPLE FREQUENCY COUNTS FOR RACE;
proc freq
data = demog
noprint;
where trt ne .;
tables trt * race / missing outpct out = race;
run;
**** FORMAT RACE N(%) AS DESIRED;
data race;
set race;
where race ne .;
length value $25;
value = put(count,4.) || ' (' || put(pct_row,5.1)||'%)';
run;
proc sort
data = race;
by race;
run;
**** TRANSPOSE THE RACE SUMMARY STATISTICS;
proc transpose
data = race
out = race(drop = _name_)
prefix=col;
by race;
var value;
id trt;
run;
**** PERFORM FISHER'S EXACT ON RACE COMPARING ACTIVE VS PLACEBO.;
proc freq
data = demog
noprint;
where race ne . and trt not in (.,2);
table race * trt / exact;
output out = pvalue exact;
run;
**** CREATE RACE FIRST ROW FOR THE TABLE.;
data label;
set pvalue(keep = xp2_fish rename = (xp2_fish = pvalue));
length label $ 85;
label = "Race";
run;
**** APPEND RACE DESCRIPTIVE STATISTICS TO RACE P VALUE ROW AND
**** CREATE RACE DESCRIPTIVE STATISTIC ROW LABELS.;
data race;
length label $ 85 col0 col1 col2 $ 25 ;
set label race;
keep label col0 col1 col2 pvalue ;
if _n_ > 1 then
label= " " || put(race,race.);
run;
**** END OF RACE STATISTICS PROGRAMMING ************************;
**** CONCATENATE AGE, GENDER, AND RACE STATISTICS AND CREATE
**** GROUPING GROUP VARIABLE FOR LINE SKIPPING IN PROC REPORT.;
data forreport;
set age(in = in1)
gender(in = in2)
race(in = in3);
group = sum(in1 * 1, in2 * 2, in3 * 3);
run;
**** DEFINE THREE MACRO VARIABLES &N0, &N1, AND &NT THAT ARE USED
**** IN THE COLUMN HEADERS FOR "PLACEBO," "ACTIVE" AND "OVERALL"
**** THERAPY GROUPS.;
data _null_;
set demog end = eof;
**** CREATE COUNTER FOR N0 = PLACEBO, N1 = ACTIVE.;
if trt = 0 then
n0 + 1;
else if trt = 1 then
n1 + 1;
**** CREATE OVERALL COUNTER NT.;
nt + 1;
**** CREATE MACRO VARIABLES &N0, &N1, AND &NT.;
if eof then
do;
call symput("n0",compress('(N='||put(n0,4.) || ')'));
call symput("n1",compress('(N='||put(n1,4.) || ')'));
call symput("nt",compress('(N='||put(nt,4.) || ')'));
end;
run;
**** USE PROC REPORT TO WRITE THE TABLE TO FILE.;
ods pdf file='C:\Users\abc\Desktop\1111.pdf';/* to define your own file path*/

options nonumber nodate ls = 100 ps=35 missing = " " formchar = "|----|+|---+=|-/\<>*";
proc report
data = forreport
nowindows
spacing = 1
headline
headskip
split = "|";
columns ("--" group label col1 col0 col2 pvalue);
define group /order order = internal noprint;
define label /display width=23 " ";
define col0 /display center width = 14 "Placebo|&n0";
define col1 /display center width = 14 "Active|&n1";
define col2 /display center width = 14 "Overall|&nt";
define pvalue /display center width = 14 " |P-value**"
f = pvalue6.4;
break after group / skip;
title1 "Company "
" ";
title2 "Protocol Name "
" ";
title3 "Table 5.3";
title4 "Demographics";
footnote1 "------------------------------------------"
"-----------------------------------------";
footnote2 "* Other includes Asian, Native Amerian, and other"
" races. ";
footnote3 "** P-values: Age = Wilcoxon rank-sum, Gender "
"= Pearson's chi-square, ";
footnote4 " Race = Fisher's exact test. "
" ";
footnote5 "Created by %sysfunc(getoption(sysin)) on"
" &sysdate9..";
run;

ods pdf close;

Super User
Posts: 10,516

Re: ODS for pdf report

ODS Output uses STYLES to control most appearance items of tables by default. Change the style  and you get difference appearance. Many of the "traditional" items such as FORMCHAR do not have any effect on ODS.

If you do not specify a style when using ODS PDF it will default to one that treats tables like one of the JOURNAL Styles.

 

Try adding Style=Default to your ODS PDF statement and see how the output changes.

 

Not that Proc Report allows style overrides to modify the appearance of cells, columns or rows.

Contributor
Posts: 66

Re: ODS for pdf report

You are correct. If I set style=default, pdf table looks some different. However it is still different from the listing output.

Super User
Posts: 9,682

Re: ODS for pdf report

Try style

ods pdf style=journal  ;



Contributor
Posts: 66

Re: ODS for pdf report

Thanks. I will try it.

Did you used %sysfunc(getoption(sysin))  macro to get a path for the code saving? it does not work for me.

Super User
Posts: 9,682

Re: ODS for pdf report

Here is the solution. Check the FOOTNOTE statement at the end of code.
Pick up one of them. Save it before running it .





data demog;
label subjid = "Subject Number"
trt = "Treatment"
gender = "Gender"
race = "Race"
age = "Age";
input subjid trt gender race age @@;
datalines;
101 0 1 3 37 301 0 1 1 70 501 0 1 2 33 601 0 1 1 50 701 1 1 1 60
102 1 2 1 65 302 0 1 2 55 502 1 2 1 44 602 0 2 2 30 702 0 1 1 28
103 1 1 2 32 303 1 1 1 65 503 1 1 1 64 603 1 2 1 33 703 1 1 2 44
104 0 2 1 23 304 0 1 1 45 504 0 1 3 56 604 0 1 1 65 704 0 2 1 66
105 1 1 3 44 305 1 1 1 36 505 1 1 2 73 605 1 2 1 57 705 1 1 2 46
106 0 2 1 49 306 0 1 2 46 506 0 1 1 46 606 0 1 2 56 706 1 1 1 75
201 1 1 3 35 401 1 2 1 44 507 1 1 2 44 607 1 1 1 67 707 1 1 1 46
202 0 2 1 50 402 0 2 2 77 508 0 2 1 53 608 0 2 2 46 708 0 2 1 55
203 1 1 2 49 403 1 1 1 45 509 0 1 1 45 609 1 2 1 72 709 0 2 2 57
204 0 2 1 60 404 1 1 1 59 510 0 1 3 65 610 0 1 1 29 710 0 1 1 63
205 1 1 3 39 405 0 2 1 49 511 1 2 2 43 611 1 2 1 65 711 1 1 2 61
206 1 2 1 67 406 1 1 2 33 512 1 1 1 39 612 1 1 2 46 712 0 . 1 49
;
run;

proc sql;
create table temp as
select 'A' as group,
       'Age(years)' as group1 length=20,
       'Active' as group2 length=20,
	   ' ' as value length=20
 from demog(obs=1)
union all
select 'A' as group,
       'Age(years)' as group1 length=20,
       'Placebo' as group2 length=20,
	   ' ' as value length=20
 from demog(obs=1)
union all
select 'A' as group,
       'Age(years)' as group1 length=20,
       'Overall' as group2 length=20,
	   ' ' as value length=20
 from demog(obs=1)
union all
select 'A' as group,
       'Age(years)' as group1 length=20,
       'Pvalue' as group2 length=20,
	   '0.95' as value length=20
 from demog(obs=1)
union all



select 'A' as group,
       'N' as group1 length=20,
       'Active' as group2 length=20,
	   put(count(age),8.-l) as value length=20
 from demog
  where trt=1 
union all
select 'A' as group,
       'N' as group1 length=20,
       'Placebo' as group2 length=20,
	   put(count(age),8.-l) as value length=20
 from demog
   where trt=0
union all
select 'A' as group,
       'N' as group1 length=20,
       'Overall' as group2 length=20,
	   put(count(age),8.-l) as value length=20
 from demog
union all
select 'A' as group,
       'N' as group1 length=20,
       'Pvalue' as group2 length=20,
	   ' ' as value length=20
 from demog(obs=1)





union all
select 'A' as group,
       'Mean' as group1 length=20,
       'Active' as group2 length=20,
	   put(mean(age),8.1 -l) as value length=20
 from demog
  where trt=1 
union all
select 'A' as group,
       'Mean' as group1 length=20,
       'Placebo' as group2 length=20,
	   put(mean(age),8.1 -l) as value length=20
 from demog
   where trt=0
union all
select 'A' as group,
       'Mean' as group1 length=20,
       'Overall' as group2 length=20,
	   put(mean(age),8.1 -l) as value length=20
 from demog
union all
select 'A' as group,
       'Mean' as group1 length=20,
       'Pvalue' as group2 length=20,
	   ' ' as value length=20
 from demog(obs=1)





union all
select 'A' as group,
       'Standard Deviation' as group1 length=20,
       'Active' as group2 length=20,
	   put(std(age),8.2-l) as value length=20
 from demog
  where trt=1 
union all
select 'A' as group,
       'Standard Deviation' as group1 length=20,
       'Placebo' as group2 length=20,
	   put(std(age),8.2-l) as value length=20
 from demog
   where trt=0
union all
select 'A' as group,
       'Standard Deviation' as group1 length=20,
       'Overall' as group2 length=20,
	   put(std(age),8.2-l) as value length=20
 from demog
union all
select 'A' as group,
       'Standard Deviation' as group1 length=20,
       'Pvalue' as group2 length=20,
	   ' ' as value length=20
 from demog(obs=1)




 
union all
select 'A' as group,
       'Minimum' as group1 length=20,
       'Active' as group2 length=20,
	   put(min(age),8.1-l) as value length=20
 from demog
  where trt=1 
union all
select 'A' as group,
       'Minimum' as group1 length=20,
       'Placebo' as group2 length=20,
	   put(min(age),8.1-l) as value length=20
 from demog
   where trt=0
union all
select 'A' as group,
       'Minimum' as group1 length=20,
       'Overall' as group2 length=20,
	   put(min(age),8.1-l) as value length=20
 from demog
union all
select 'A' as group,
       'Minimum' as group1 length=20,
       'Pvalue' as group2 length=20,
	   ' ' as value length=20
 from demog(obs=1)







 
union all
select 'A' as group,
       'Maximum' as group1 length=20,
       'Active' as group2 length=20,
	   put(max(age),8.1-l) as value length=20
 from demog
  where trt=1 
union all
select 'A' as group,
       'Maximum' as group1 length=20,
       'Placebo' as group2 length=20,
	   put(max(age),8.1-l) as value length=20
 from demog
   where trt=0
union all
select 'A' as group,
       'Maximum' as group1 length=20,
       'Overall' as group2 length=20,
	   put(max(age),8.1-l) as value length=20
 from demog
union all
select 'A' as group,
       'Maximum' as group1 length=20,
       'Pvalue' as group2 length=20,
	   ' ' as value length=20
 from demog(obs=1)





/****************************/
union all
 select 'B' as group,
       'Gender' as group1 length=20,
       'Active' as group2 length=20,
	   ' ' as value length=20
 from demog(obs=1)
union all
select 'B' as group,
       'Gender' as group1 length=20,
       'Placebo' as group2 length=20,
	   ' ' as value length=20
 from demog(obs=1)
union all
select 'B' as group,
       'Gender' as group1 length=20,
       'Overall' as group2 length=20,
	   ' ' as value length=20
 from demog(obs=1)
union all
select 'B' as group,
       'Gender' as group1 length=20,
       'Pvalue' as group2 length=20,
	   '0.268' as value length=20
 from demog(obs=1)





union all
select 'B' as group,
       'Male' as group1 length=20,
       'Active' as group2 length=20,
	   catx(' ',put(count(gender),8.-l),'(',
       put(count(gender)/(select count(gender) from demog where trt=1),percent8.1)
       ,')') as value length=20
 from demog
  where trt=1 and gender=1
union all
select 'B' as group,
       'Male' as group1 length=20,
       'Placebo' as group2 length=20,
	   catx(' ',put(count(gender),8.-l),'(',
       put(count(gender)/(select count(gender) from demog where trt=0),percent8.1)
       ,')') as value length=20
 from demog
  where trt=0 and gender=1
union all
select 'B' as group,
       'Male' as group1 length=20,
       'Overall' as group2 length=20,
	   catx(' ',put(count(gender),8.-l),'(',
       put(count(gender)/(select count(gender) from demog),percent8.1)
       ,')') as value length=20
 from demog
  where gender=1
union all
select 'B' as group,
       'Male' as group1 length=20,
       'Pvalue' as group2 length=20,
	   ' ' as value length=20
 from demog(obs=1)






union all
select 'B' as group,
       'Female' as group1 length=20,
       'Active' as group2 length=20,
	   catx(' ',put(count(gender),8.-l),'(',
       put(count(gender)/(select count(gender) from demog where trt=1),percent8.1)
       ,')') as value length=20
 from demog
  where trt=1 and gender=2
union all
select 'B' as group,
       'Female' as group1 length=20,
       'Placebo' as group2 length=20,
	   catx(' ',put(count(gender),8.-l),'(',
       put(count(gender)/(select count(gender) from demog where trt=0),percent8.1)
       ,')') as value length=20
 from demog
  where trt=0 and gender=2
union all
select 'B' as group,
       'Female' as group1 length=20,
       'Overall' as group2 length=20,
	   catx(' ',put(count(gender),8.-l),'(',
       put(count(gender)/(select count(gender) from demog),percent8.1)
       ,')') as value length=20
 from demog
  where gender=2
union all
select 'B' as group,
       'Female' as group1 length=20,
       'Pvalue' as group2 length=20,
	   ' ' as value length=20
 from demog(obs=1)



/***************************/
union all
 select 'C' as group,
       'Race' as group1 length=20,
       'Active' as group2 length=20,
	   ' ' as value length=20
 from demog(obs=1)
union all
select 'C' as group,
       'Race' as group1 length=20,
       'Placebo' as group2 length=20,
	   ' ' as value length=20
 from demog(obs=1)
union all
select 'C' as group,
       'Race' as group1 length=20,
       'Overall' as group2 length=20,
	   ' ' as value length=20
 from demog(obs=1)
union all
select 'C' as group,
       'Race' as group1 length=20,
       'Pvalue' as group2 length=20,
	   '0.927' as value length=20
 from demog(obs=1)
 
 
 
 
 
union all
select 'C' as group,
       'White' as group1 length=20,
       'Active' as group2 length=20,
	   catx(' ',put(count(race),8.-l),'(',
       put(count(race)/(select count(race) from demog where trt=1),percent8.1)
       ,')') as value length=20
 from demog
  where trt=1 and race=1
union all
select 'C' as group,
       'White' as group1 length=20,
       'Placebo' as group2 length=20,
	   catx(' ',put(count(race),8.-l),'(',
       put(count(race)/(select count(race) from demog where trt=0),percent8.1)
       ,')') as value length=20
 from demog
  where trt=0 and race=1
union all
select 'C' as group,
       'White' as group1 length=20,
       'Overall' as group2 length=20,
	   catx(' ',put(count(race),8.-l),'(',
       put(count(race)/(select count(race) from demog),percent8.1)
       ,')') as value length=20
 from demog
  where race=1
union all
select 'C' as group,
       'White' as group1 length=20,
       'Pvalue' as group2 length=20,
	   ' ' as value length=20
 from demog(obs=1)
 
 
 

 
union all
select 'C' as group,
       'Black' as group1 length=20,
       'Active' as group2 length=20,
	   catx(' ',put(count(race),8.-l),'(',
       put(count(race)/(select count(race) from demog where trt=1),percent8.1)
       ,')') as value length=20
 from demog
  where trt=1 and race=2
union all
select 'C' as group,
       'Black' as group1 length=20,
       'Placebo' as group2 length=20,
	   catx(' ',put(count(race),8.-l),'(',
       put(count(race)/(select count(race) from demog where trt=0),percent8.1)
       ,')') as value length=20
 from demog
  where trt=0 and race=2
union all
select 'C' as group,
       'Black' as group1 length=20,
       'Overall' as group2 length=20,
	   catx(' ',put(count(race),8.-l),'(',
       put(count(race)/(select count(race) from demog),percent8.1)
       ,')') as value length=20
 from demog
  where race=2
union all
select 'C' as group,
       'Black' as group1 length=20,
       'Pvalue' as group2 length=20,
	   ' ' as value length=20
 from demog(obs=1) 
 
 
 


 
union all
select 'C' as group,
       'Other*' as group1 length=20,
       'Active' as group2 length=20,
	   catx(' ',put(count(race),8.-l),'(',
       put(count(race)/(select count(race) from demog where trt=1),percent8.1)
       ,')') as value length=20
 from demog
  where trt=1 and race=3
union all
select 'C' as group,
       'Other*' as group1 length=20,
       'Placebo' as group2 length=20,
	   catx(' ',put(count(race),8.-l),'(',
       put(count(race)/(select count(race) from demog where trt=0),percent8.1)
       ,')') as value length=20
 from demog
  where trt=0 and race=3
union all
select 'C' as group,
       'Other*' as group1 length=20,
       'Overall' as group2 length=20,
	   catx(' ',put(count(race),8.-l),'(',
       put(count(race)/(select count(race) from demog),percent8.1)
       ,')') as value length=20
 from demog
  where race=3
union all
select 'C' as group,
       'Other*' as group1 length=20,
       'Pvalue' as group2 length=20,
	   ' ' as value length=20
 from demog(obs=1) 
  
;
quit;

proc transpose data=temp out=want(drop=_name_);
 by group group1 notsorted;
 var value;
 id group2;
run;

ods pdf file='/folders/myfolders/want.pdf' style=journal;
title "Company";
footnote1 "Created by %sysget(SAS_EXECFILENAME) on  &sysdate9.";
footnote2 "Created by &_sasprogramfile on &sysdate9.";
proc report data=want nowd;
define group/group noprint;
define group1/ ' ';
compute before group;
 line ' ';
endcomp;
run;
ods pdf close;


Contributor
Posts: 66

Re: ODS for pdf report

The code is cool. Thanks.

☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 8 replies
  • 355 views
  • 0 likes
  • 4 in conversation