Save Webview as PDF

Rusty

Well-Known Member
Licensed User
Longtime User
Is there a way to save the contents of a Webview as a PDF?
Thanks,
Rusty
 

Rusty

Well-Known Member
Licensed User
Longtime User
Thanks Erel, I'm trying to figure out how one would save the Webview to a bitmap...Still looking but advice would help.
Thanks,
Rusty
 
Upvote 0

Rusty

Well-Known Member
Licensed User
Longtime User
I've successfully stored a bitmap file as a .jpg.
I've been able to capture it into a bitmap, but when I try to add the bitmap to a PDF (using PDFWriter as suggested by Erel), I get an out of memory error
B4X:
PackageAdded: package:b4a.example
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
PDFWriter has been initialized.
main_capturetimer_tick (B4A line: 62)
PDFWriter1.ConverseDocument
java.lang.OutOfMemoryError
    at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:94)
    at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:145)
    at java.lang.StringBuilder.append(StringBuilder.java:216)
    at com.rootsoft.pdfwriter.PDFDocument.toPDFString(PDFDocument.java:69)
    at com.rootsoft.pdfwriter.PDFWriter.asString(PDFWriter.java:113)
    at com.rootsoft.pdfwriter.myPDFWriter.ConverseDocument(myPDFWriter.java:90)
    at b4a.example.main._capturetimer_tick(main.java:346)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:167)
    at anywheresoftware.b4a.objects.Timer$TickTack.run(Timer.java:103)
    at android.os.Handler.handleCallback(Handler.java:605)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4424)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
    at dalvik.system.NativeStart.main(Native Method)
my code:
B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim WebView1 As WebView
    Dim ImageView1 As ImageView
    Dim BMPPage As Bitmap
    Dim CaptureTimer As Timer
    Dim retries As Int = 0
    
    
    Dim PDFWriter1 As PDFWriter
    Dim PaperSize As PDFPaperSizes
    Dim Fonts As PDFStandardFonts
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    CaptureTimer.Initialize("CaptureTimer", 200)
    CaptureTimer.Enabled = False
    
    Activity.LoadLayout("Main")
    WebView1.BringToFront
    WebView1.SetLayout(0, 0, 50%x, 50%y)
    WebView1.LoadUrl("file:///mnt/sdcard/Mysystem/reports/temp.htm")    
    BMPPage.InitializeMutable(WebView1.Width, WebView1.Height)
    CaptureTimer.Enabled = True
End Sub

Sub CaptureTimer_Tick
    Try
        CaptureTimer.Enabled = False    
        
        Dim Out As OutputStream
        Out = File.OpenOutput("/mnt/sdcard/Mysystem/reports/", "test.jpg", False)
        WebView1.CaptureBitmap.WriteToStream(Out, 100, "JPEG")
        Out.Close

        BMPPage = WebView1.CaptureBitmap
        'do whatever you need with the bitmap
        PDFWriter1.Initialize("PDFWriter1", PaperSize.A4_HEIGHT, PaperSize.A4_WIDTH)
        PDFWriter1.addImage(0, PaperSize.A4_HEIGHT, BMPPage)
        PDFWriter1.ConverseDocument
Return
    Catch
        CaptureTimer.Enabled = True
        Log("Failed to capture: " & LastException & " "  & retries)
        retries = retries + 1
        If retries = 3 Then CaptureTimer.Enabled = False
    End Try
End Sub
Sub PDFWriter1_ConversionDone (Content As String)
    Dim    PDFContent As String = Content
    PDFWriter1.outputToFile("/mnt/sdcard/Mysystem/reports/", "TEST.PDF", PDFContent,"ISO-8859-1")
    ToastMessageShow("Conversion has been done.",False)
    
End Sub
Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

The error occurs on the conversedocument statement.
Any help/ideas are appreciated.
Rusty
 
Upvote 0

Rusty

Well-Known Member
Licensed User
Longtime User
I don't want to sound like complaining, the PDFWriter is great if you create your PDF on your own, but in saving an HTML page (results) to it by saving the WebView to a JPG/PNG, then inserting it into the PDF is not acceptable.
Here's why:
I've inserted a 35K JPG into the PDF, it's the only thing in it; the resultant PDF is unreadable (resolution is very fuzzy).
In order to get the PDFWriter to accept an insert of a JPG, the file has to be this small. The original JPG is 320K and is very readable.
I had to save and reload the JPG using initializesample
B4X:
Dim Out As OutputStream
        Out = File.OpenOutput(MyFolder, "tempbefore.jpg", False)
        WebView1.CaptureBitmap.WriteToStream(Out, 100, "JPEG")
        Out.Close
        Dim b As Bitmap
        b.Initialize(Main.sdcard.specificreports, "tempbefore.jpg")        'save it so we can reload/sample
'Log("before bmp size " & b.Height & " x " & b.Width)
        BMPPage.InitializeSample(MyFolder, "tempbefore.jpg", 250, 300)    'shrink it down (pdfwriter won't take big images)
'Log("bmp size " & BMPPage.Height & " x " & BMPPage.Width)
If I up the size in the initializesample to something readable (even a small increment from the above), the OUT OF MEMORY error occurs.
It looks like the insertimage is for a small icon file or something very small.
Am i missing something? Advice and suggestions appreciated.
Rusty

Klaus,
I tried running your PDFBitmap project and get the same results...out of memory. If this works on your tablet, then maybe it is an environmental issue on mine.
 
Last edited:
Upvote 0
Top