G GabrielM Member Licensed User Longtime User Aug 22, 2020 #1 I have previously been using the jPOI to the rescue example (in B4J) to substitute string variables for specific words in a MS-Word (DOC) file and it was performing great. String variables I am using inside the file text are of the format: "<<variable>>" . Would like to try now to do something similar in B4A, though it seems the jPOI could not be used for some reasons, therefore I thought to use the RTF file format. Seen a reference to a Java library: "com.tutego.jrtf" that has a class which is able to make variable substitution in an existing RTF file: RtfTemplate Class Asking for some guidance on how to use this class specifically the .inject method in B4A, so I could open an existing RTF, replace the variables (I could have them as key/value Map) and write the resulting file to another file name.
I have previously been using the jPOI to the rescue example (in B4J) to substitute string variables for specific words in a MS-Word (DOC) file and it was performing great. String variables I am using inside the file text are of the format: "<<variable>>" . Would like to try now to do something similar in B4A, though it seems the jPOI could not be used for some reasons, therefore I thought to use the RTF file format. Seen a reference to a Java library: "com.tutego.jrtf" that has a class which is able to make variable substitution in an existing RTF file: RtfTemplate Class Asking for some guidance on how to use this class specifically the .inject method in B4A, so I could open an existing RTF, replace the variables (I could have them as key/value Map) and write the resulting file to another file name.
DonManfred Expert Licensed User Longtime User Aug 22, 2020 #2 Isn´t RTF just a text file? B4X: File.Copy(File.DirAssets,"orgfile.rtf",File.DirInternal,"orgfile.rtf") Dim rtf As String = File.ReadString(File.DirInternal,"orgfile.rtf") ' replace the placeholder(s) in rtf File.WriteString(File.DirInternal,"newfile.rtf",rtf) Upvote 0
Isn´t RTF just a text file? B4X: File.Copy(File.DirAssets,"orgfile.rtf",File.DirInternal,"orgfile.rtf") Dim rtf As String = File.ReadString(File.DirInternal,"orgfile.rtf") ' replace the placeholder(s) in rtf File.WriteString(File.DirInternal,"newfile.rtf",rtf)
G GabrielM Member Licensed User Longtime User Aug 22, 2020 #3 Thanks Manfred, The RTF file its kind of big in size, and not very sure I could handled with using regex to cover some 150 different placeholders, that is why I turned to the jRTF lib, hoping it would be simpler to pass a Map with those placeholders, while I could learn some on using external jars. Upvote 0
Thanks Manfred, The RTF file its kind of big in size, and not very sure I could handled with using regex to cover some 150 different placeholders, that is why I turned to the jRTF lib, hoping it would be simpler to pass a Map with those placeholders, while I could learn some on using external jars.
G GabrielM Member Licensed User Longtime User Aug 22, 2020 #4 This is what I currently try with regex, after I read line by line as strings from RTF file, though honestly I am looking for some help on how to use that external jar - jRtf - RtfTemplate Class specifically. B4X: public Sub tryReplace Dim data As String ' this is the example RTF file read as text data = "We have <<ADDRESSLINE1>> as buld and <<ADDRESSLINE2>> not ready" ' Dim matcher1 As Matcher matcher1 = Regex.Matcher("<<[^>]+>>", data) ' regex pattern for placeholders Do While matcher1.Find = True 'Log(matcher1.Match) Select matcher1.Match ' care for specific placeholders Case "<<ADDRESSLINE1>>" data = data.Replace("<<ADDRESSLINE1>>", "tutego") Case "<<ADDRESSLINE2>>" data = data.Replace("<<ADDRESSLINE2>>", "Sonsbeck") End Select Loop ' Log(data) End Sub Upvote 0
This is what I currently try with regex, after I read line by line as strings from RTF file, though honestly I am looking for some help on how to use that external jar - jRtf - RtfTemplate Class specifically. B4X: public Sub tryReplace Dim data As String ' this is the example RTF file read as text data = "We have <<ADDRESSLINE1>> as buld and <<ADDRESSLINE2>> not ready" ' Dim matcher1 As Matcher matcher1 = Regex.Matcher("<<[^>]+>>", data) ' regex pattern for placeholders Do While matcher1.Find = True 'Log(matcher1.Match) Select matcher1.Match ' care for specific placeholders Case "<<ADDRESSLINE1>>" data = data.Replace("<<ADDRESSLINE1>>", "tutego") Case "<<ADDRESSLINE2>>" data = data.Replace("<<ADDRESSLINE2>>", "Sonsbeck") End Select Loop ' Log(data) End Sub
DonManfred Expert Licensed User Longtime User Aug 22, 2020 #5 i am not familar with this library, even i did not know there is one. ? Never was in the need to use RTF. Sorry i can´t help any further. Upvote 0
i am not familar with this library, even i did not know there is one. ? Never was in the need to use RTF. Sorry i can´t help any further.
Erel B4X founder Staff member Licensed User Longtime User Aug 23, 2020 #6 What is the problem with the regex solution? Is it too slow? It can be optimized. Upvote 0
G GabrielM Member Licensed User Longtime User Aug 23, 2020 #7 Erel said: What is the problem with the regex solution? Is it too slow? It can be optimized. Click to expand... The regex solution just works ok, no issues. I am trying now to pass all "placeholders" and their replacement values as a Map. Would be great if I could optimize it, yes. Thank you. Upvote 0
Erel said: What is the problem with the regex solution? Is it too slow? It can be optimized. Click to expand... The regex solution just works ok, no issues. I am trying now to pass all "placeholders" and their replacement values as a Map. Would be great if I could optimize it, yes. Thank you.
Erel B4X founder Staff member Licensed User Longtime User Aug 23, 2020 #8 I wouldn't try to optimize it if it works fast enough as the optimization will make it more complicated. The idea is to build a single regex pattern and update the string in a single pass. It is done here: https://www.b4x.com/android/forum/threads/csbuilder-marking-based-on-regex-pattern.83002/#content GabrielM said: I am trying now to pass all "placeholders" and their replacement values as a Map. Click to expand... Code: For Each key As String In Replacements.Keys TryReplace(Key, Replacements.Get(Key)) Next Upvote 0
I wouldn't try to optimize it if it works fast enough as the optimization will make it more complicated. The idea is to build a single regex pattern and update the string in a single pass. It is done here: https://www.b4x.com/android/forum/threads/csbuilder-marking-based-on-regex-pattern.83002/#content GabrielM said: I am trying now to pass all "placeholders" and their replacement values as a Map. Click to expand... Code: For Each key As String In Replacements.Keys TryReplace(Key, Replacements.Get(Key)) Next