Sunday, October 4, 2009

Handling Text Wrapping with Fixed Rows in BI Desktop Publisher


After seeing Tim Dexter post about fixed line and row filler decided to post about the handling string wrapping in the template.
Ok let me start explaining how I handle the string wrapping. Before that let me let me tell you the requirement.
1. Need to display fixed lines.
2. If there are only few lines and the page is not filled then we need to print blank lines to fill the page.
3. At the end of the report we need to display the summary as shown above.
4. At the end of the rows including the rows with values and blank rows we need to print a line to end the box.
Here is the invoice template screen shot,
To handle the string wrapping I had taken the number of characters that will fit into item description field (this is expected to wrap), in my example 24 characters will fit in a single line. 
Here is the mini logic i have will also consider single word wrapping to next line.
ln_Act_lgth := length(lc_data);
ln_lgth:=0;
ln_row:=1;   
loop
       -- Get the first word of the string without the space.
    lc_word := substr(lc_data,1,instr(lc_data,' ')-1);
    --get the length of the existing word on the current line  with the current word.       
    ln_lgth := ln_lgth + NVL(length(lc_word),0);         
    --Add 1 for space when calculating the total length so.
    ln_tot_lgth := ln_tot_lgth + NVL(length(lc_word),0)+1;   
    --if length of the existing word on the current line with the current word
    --is more than 24 means then the line will break into two.
    IF ln_lgth >= 24 THEN
      ln_row := ln_row+1;
      ln_lgth:= NVL(length(lc_word),0);
    END IF;
    ln_lgth := ln_lgth+1;
    exit when  ln_tot_lgth >= ln_Act_lgth;
    --get the balance remaining string apart from the current word.
    lc_data := substr(lc_data,instr(lc_data,' ')+1);       
end loop;
And again as per my example 36 lines will fit into one page (including the summary).
Now let me give you the pseudocode of my logic.
START
Loop
1. Print the invoice row.
2. Keep the count of number of lines each invoice row is taking. ex: v_rowcount = v_rowcount + length(ITEM_DESCRIPTION) MOD 24(this is the text wrapping handler)

IF v_rowcount >= 36 THEN
§ Print the line to close the box.
§ Reset v_rowcount to zero.

END IF;
END LOOP
3. Take the balance rows available to print empty lines (ex v_balance_line = v_rowcount - 36)
4. Now I will have to cases. First is there may not be sufficient lines available to print the summary. In this case we need to display empty lines and then print at the end of next page. So,

IF v_balance_lines <>) THEN
§ Print blank lines for remaining lines to find the number of blank rows to be printed use the variable v_rowcount. so here the no of blank lines will be 36 - (v_rowcount)
§ Print the line to close the box.
§ Enable a flag to say we need to print empty rows in the 29 empty rows in the next page, So that the summary comes at the end.
ELSE IF v_balance_lines > 7 THEN
§ Print blank lines by making sure you leave 7 lines to print summary. to find the number of blank rows to be printed use the variable v_rowcount. so here the no of blank lines will be 36 - (v_rowcount+ 7)
§ Print the line to close the box.
§ Print the summary
END IF;
5. Check whether the flag is enables to print 29 blank lines. If yes,
§ Print 29 blank lines.
§ Print the line to close the box.
§ Print the summary
END
That’s all. If you closely watch the above pseudocode you will get the logic of handling text wrapping.
I know as usual I had not formatted this post well But for your convenience I had attached the sample RTF and XML file here


6 comments:

Unknown said...

Hi Lakshmanan,

I am having one doubt in this logic...

Assume that length of description was 48, then length(ITEM_DESCRIPTION) MOD 24 ie(48 mod 24 will return 0 ). So, as per our logic how many rows it will take instead of printing in 2 rows... Plz Clarify me..

AK Lakshmanan said...

Raj,

Thanks for noticing that. Actually I changed that logic to consider individual word wrapping also but forgot to update the blog.

Here is the new logic,
ln_Act_lgth := length(lc_data);
ln_lgth:=0;
ln_row:=1;
loop
-- Get the first word of the string without the space.
lc_word := substr(lc_data,1,instr(lc_data,' ')-1);
--get the length of the existing word on the current line with the current word.
ln_lgth := ln_lgth + NVL(length(lc_word),0);
--Add 1 for space when calculating the total length so.
ln_tot_lgth := ln_tot_lgth + NVL(length(lc_word),0)+1;
--if length of the existing word on the current line with the current word
--is more than 24 means then the line will break into two.
IF ln_lgth >= 24 THEN
ln_row := ln_row+1;
ln_lgth:= NVL(length(lc_word),0);
END IF;
ln_lgth := ln_lgth+1;
exit when ln_tot_lgth >= ln_Act_lgth;
--get the balance remaining string apart from the current word.
lc_data := substr(lc_data,instr(lc_data,' ')+1);
end loop;

Ronald Maus said...

Hi Lakshmanan,Just wanted to know if the string wrapping could be done in the RTF?
New BIP user

AKlakshmanan said...

Yes Possible.

Gc said...

Hi Lakshmanan,

  I do not see Loop and end loop in attached template.  Why? Did you uploaded a wrong template??

Regards,
 

Arun P said...

HI Lakshmanan,


Can u give the final finished template as an attachment .That will be a real great help for lots of people.


Thanks in advance
Arun P.

Post a Comment