Hello all
does someone have DLL prototypes for
https://wkhtmltopdf.org/libwkhtmltox/pdf_8h.html
Thanks.
I use the commandline version and run it ie
commandLine = ‘wkhtmltopdf.exe -q --orientation Portrait --image-quality 100 --print-media-type ‘&’"’&CLIP(pDocumentnaam)&‘" "’&clip(WisLaatsteMap(glo:uncmapbijlagen))&‘\DOC_BRON\bijlage.pdf’&‘"’ ! Add any additional parameters here
Yes, I use it on same way but the problem is - it does not work when you have image inside HTML, using full url, like
<img src="http://localhost:1111/doc/img.jpg" width="300">
it just hangs. I figured that just today so I presume it will also not work using DLL
Now I need to figure out how to handle HTML when user pasted content with image.
Thanks anyway.
That is not true, I am calling wkhtmltopdf.exe from both an .exe (running as a service) and .dll and it works fine. And it works with images, although I must admit these are embedded images.
Did you test your command line string in a DOS box to see if it works there?
Maybe it make a difference if you use the API ShellExecute versus the Clarion RUN statement. It might worth a try.
It works if image is stored as base64. It also works if image use internet domain but when using localhost - it does not work.
I presume it is related to answer from local server but I found how to solve this: when user paste image into html editor, it is converted to base64. When user upload image, I use …/doc/image.png (instead of http://localhost:1111/doc/image.png and it works fine.
I’m using ShellExecuteEx with SW_HIDE parameter.
That might be true. I am using localhost and that might be the reason why I started using embedded images. Good you figured it out.
How can images in html code be found and changed to base64. I do have stringtheory
The Clarion SystemStringClass has this technique…
DynString SystemStringClass
GetUploadDeliveryPod ROUTINE
Local:ImageString = ''
IF del:pod AND EXISTS(del:pod)
Err# = DynString.FromFile(del:pod) ! Load the image into a string
IF NOT Err#
Local:ImageString = 'data:image\/png;base64' & DynString.ToBase64() ! Base64 encode it
END
END
EXIT
Hi Geoff,
Thanks i like the Clarion SystemStringClass.
What i also wanted to know is how can i find all the img tags with a file refence in a htmlfile to substitute them to base64)
Do you have existing HTML code or do you make it yourself in your application? If the latter then I would make it an embedded image directly instead. That can be done like:
stFoto StringTheory
stPagina StringTheory
stFoto.FromFile(<MytPath>)
stFoto.Base64Encode(st:noWrap)
stPagina.Append('<div class="foto"><a href="https://' & CLIP(pNaam) & '">')
stPagina.Append('<img src="data:image/png;base64,')
stPagina.Append(stFoto.GetValue())
stPagina.Append('"></a></div>')
If you need to change existing HTML code that wil be a lot more work. First you need to have the whole HTM code in a StringTheory object. Then you can search for the beginning of image part like st.FindBetween('<img','>')
which will give you the part with the image in what need to be changed with the code above. Repeat the for every image.
I only answered the easy part!
- You need to have the image file.
- So, is it a local html file or a remote html file? If local you probably already know the location of the file.
- If remote, you’re going to have to find the image locally, the location of which is determined by your browser.
- So, how are you browsing the HTML file, if you are?
Just my thought, the easy part
The html is from an external wysiwyg editor (TxControl).
For now i loop (backwords) thrue the whole html text an can ie find:
<img src=“…/…/logo.jpg” width=“189” “height=105” style=“…” title=“logo.jpg” alt=“[image]”/ >
Can this be translated to base64? And if so how?
PS In the search loop i skip image src which start with ‘http://’ or ‘cid:’ or empty filenames
yes provided you have access to the file “…/…/logo.jpg” then read it into ST and do more or less as Koen showed above. Maybe simplify it a bit and just replace the reference to logo.jpg with the base64 encoded text. Off the top of my head, something like:
st stringTheory
img stringTheory
fname stringTheory ! filename of image
lStart long,auto
lEnd long,auto
srcStart long,auto
srcEnd long,auto
replaces long,auto
code
if ~st.loadFile('myHTML.htm')
message('warning: html file not loaded: ' & st.lastError)
<error> ! return or exit etc.
end
replaces = 0
lStart = 0
loop
lStart += 1
lEnd = 0
st.findBetweenPosition('<<img ','/>',lStart,lEnd)
if lStart = 0 then break. ! start/end not found
if lStart > lEnd then cycle. ! no contents between start/end
srcStart = lStart
srcEnd = lEnd
st.findBetweenPosition('src="','"',srcStart,srcEnd,st:NoCase)
if srcStart = 0 or srcStart > srcEnd then cycle.
fName.setValue(st.slice(srcStart,srcEnd))
fName.trim()
if fName.startsWith('http:') or fName.startsWith('cid:') then cycle.
if ~img.loadFile(fName.getValue()) ! load the image
st.trace('warning: file [' & fName.getValue() & '] not loaded: ' & st.lastError)
cycle
end
if img.len() = 0
st.trace('warning: zero length file [' & fName.getValue() & ']')
cycle
end
img.base64Encode(st:noWrap)
replaces += st.replace(st.slice(srcStart,srcEnd), |
'data:image/' & fName.extensionOnly() & |
';base64,' & img.getValue(),1,srcStart,srcEnd)
end
if replaces then st.saveFile('myUpdatedHTML.htm').
As I say that’s off the top of my head and totally untested but should give you the general idea. Yell out if you have any problems,
cheers
Geoff R
See my example above. Extract the filename from the src=“…/…/logo.jpg”
part and put that in a variable MyFile. Then with StringTheory:
stFoto.LoadFile(MyFile)
stFoto.Base64Encode(st:noWrap)
Once converted put the StingTheory object back into your HTML text replacing the original part. I assume the image file is local. If it is on an other URL then I don’t know how to get it in a StringTheory object.
Have a look at st.findbetween()
You can loop through your html string using the example code in the st docs and search for…
st.findbeteen(‘<img src=“’, '",…)
this will give you the name of the image, then as has been suggested previously, use whatever tool you like to convert it into base64
e.g. what Koen suggested above.
The ST methods are certainly powerful and if you look at my suggested code above, I used another variation st.findBetweenPosition() which is similar but doesn’t return the string between - just the start and end positions:
and
perhaps a word about the check after the call is in order:
by default the returned positions exclude the start and end parameters and just give you what is between. If you wanted to include the start and end parameters there is a separate “Exclusive” parameter (which defaults to true) that you can set to false instead.
anyway in this case we are excluding the start and end parameters (the default…) so consider the string ‘abcdefg’
if we said between ‘b’ and ‘e’ then it would return 3 for start and 4 for end.
if we said between ‘b’ and ‘d’ then it would return 3 for start and 3 for end.
if we said between ‘b’ and ‘c’ then it would return 3 for start and 2 for end.
hence you can see why we check
if srcStart = 0 or srcStart > srcEnd
as that checks if the start/end parameters were found and also if there was any contents between them.
Thanks All !
Hope i have time this weekend to experiment with the beautifull code snippits and tips
Hi All,
Because my image filename in html code starts with …/…/…/ and then starts the path from the application directory it will not be found with:
img.loadFile(fName.getValue())
What is a good way to change …/…/…/
I tried …....\ but it didn’t make any difference
maybe try changing ‘…/…/…/’ to ‘.\’ using replace:
fName.replace('…/…/…/','.\')
or maybe just remove that completely. Lots of ways to do that:
fName.replace('…/…/…/','')
or
fName.remove('…/…/…/')
or
! allow for a variable number of .../
fName.replace('…/','')
you will have to experiment but maybe you also need to replace forward slashes with back slashes for Windows?
fName.replace('/','\')
anyway let us know how you go and what you end up using
cheers
Geoff R