4

i have a VFP that rendered in PDF format for my Quote. And due to the limitation whereby long text doesnt word-wrap in my table , i decided to loop through my long text content and put a line break
after x characters.

I am doing this in my VFP exntesion class like this:

public class quote_ViewQuotePDFExtension {

    Pattern p = Pattern.compile('[\\p{IsHan}\\p{IsHiragana}\\p{IsKatakana}\\p{IsHangul}]');
    public List<QuoteLineItem> ungrp_quols {get;set;}

    public quote_ViewQuotePDFExtension(ApexPages.StandardController stdcont){
        Id quote_id = slquote.id;


        for(QuoteLineItem itm: [Select Id, UnitPrice, long_text_content__c from QuoteLineItem where QuoteId =: quote_id]){

             if(itm.long_text_content__c != null){
                for(Integer i=0; i< itm.long_text_content__c.length(); i++){

                //loop each characters and put <br> after certain count
               // i even have regex to check if the characters is chineses, japanese or korean and increase my count + 2 else + 1

                }
               UngroupQuolItems.Rich_Line_Item_Description__c = format_str;
             }

           ungrp_quols.add(UngroupQuolItems);
         }

    }

}

of course my extesion have other logic running as well. So i would like to know if this is kind of bad design to loop each characters in my long text content to append a <br>. Will this slow down the performance like take longer to render the PDF or hit governor limits.

or it would be better to do it as trigger to append the the long text content when insert & update?

Thanks.

1
  • I had similar requirement to wrap words after specific characters, implemented it similarly. It would not affect performance much. Regarding governor limits, you are just adding loops and not making any additional SOQL calls, so should be fine. Trigger would be an overkill and difficult to maintain. – Raul Sep 18 '16 at 15:32
2

You'd get far better performance using replaceAll:

UngroupQuolItems.Rich_Line_Item_Description__c =
   itm.long_text_content__c.replaceAll('(.{100})','$1<br/>');

No loops, no substrings, just pure speed. Adjust 100 to whatever number you feel is appropriate. More complex patterns are also possible, it really depends on your exact needs.

6
  • Could you elaborate on how this regex works? It's very cool, I tried to dig into it today but couldn't really understand how it works in this context. – gorav Sep 18 '16 at 23:45
  • yes, can you explain a little bit more how this regex works? i have similar problem as well and my content is rich text, i do not want to count any text within <html> tag as 1, just pure text towards my max characters, is this also possible in this regex? – user2074703 Sep 19 '16 at 1:57
  • @gorav Does this document help? – sfdcfox Sep 19 '16 at 5:41
  • Thanks, the doc along w the Java docs have helped me get my bearings. Allow me to butcher the explanation for how this works. The . matches any character. The {100} is a quantifier, so together the .{100} matches each substring of 100 characters. The $1 is a placeholder, representing the first match group. So all together, the replaceall method will match each substring of 100 characters, and replace it w the matched string plus a <br>. Had not seen placeholders before. Very neat solution. – gorav Sep 19 '16 at 16:23
  • @gorav It's reasonably obscure, as $1 doesn't appear in the docs anywhere that I can tell, but it's worked reliably for as long as I've known about it. You'll probably "rarely" have a use for it, but it sure is handy right when you need it. – sfdcfox Sep 19 '16 at 16:51
2

Generally best to keep presentation formatting out of the stored data and only apply formatting when needed as you are doing.

I'd be a little cautious about stepping through each character especially if the text can be thousands of characters long. (More to avoid sluggish performance that the 10s CPU limit.) This sort of loop to split the text up would be less expensive:

Integer size = 10;
String text = 'abcdefghijklmnopqrstuvwxyz';

String[] parts = new String[] {};
for (Integer start = 0; start < text.length(); start += size) {
    parts.add(text.substring(start, Math.min(text.length(), start + size)));
}

assuming you can do your Chinese/Japanese/Korean determination up front.

In controller extension form:

public with sharing class quote_ViewQuotePDFExtension {

    private static final Integer MAX = 100;

    private ApexPages.StandardController sc;

    public quote_ViewQuotePDFExtension(ApexPages.StandardController sc) {
        this.sc = sc;
    }
    public String [] getLongTextContentParts() {
        String[] parts = new String[] {};
        for (QuoteLineItem item : [
                Select long_text_content__c
                from QuoteLineItem
                where QuoteId = :sc.getId()
                ]) {
            String text = item.long_text_content__c;
            if (!String.isEmpty(text)) {
                for (Integer start = 0; start < text.length(); start += MAX) {
                    parts.add(text.substring(start, Math.min(text.length(), start + MAX)));
                }
            }
        }
        return parts;
    }
}
1
  • !String.isEmpty(text), you mean. I found a no-loop variant to this problem as well. – sfdcfox Sep 18 '16 at 18:17
0

Use replaceAll function I want add br tag each n space in Latin string such as:

n = 5

input:

Aliquam suscipit nisl luctus urna finibus faucibus. Suspendisse posuere dui vel egestas lobortis.

expected out:

Aliquam suscipit nisl luctus urna<br/> finibus faucibus. Suspendisse posuere dui<br/> vel egestas lobortis.

I have been below code but not success, any other way to solve this issue?

String str = 'Aliquam suscipit nisl luctus urna finibus faucibus. Suspendisse posuere dui vel egestas lobortis.';
str = str.replaceAll('([ .]){5}', '$1``<br/>``');

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.