Main Issue: How to export PDF files using one PDF per page from a LibreOffice 
BASIC macro
Related Issue: How to change any values with a macro when exporting to PDF files

I've left my original question intact, but this includes the answer - this code 
and the two links will show you what you need to know to write a macro for 
LibreOffice that can export a PDF with whatever settings you desire.  I'm 
saving the code to last (right before the text of the original question).

These web pages are geared toward Java, and things do work differently in Java, 
in many cases, than they do in BASIC.  The first is a tutorial on how to export 
a PDF file from LO in Java:

http://wiki.openoffice.org/wiki/API/Tutorials/PDF_export

A few issues to note if you're looking through this:
- You do not need most of the objects created in the Java program.  You can use 
ThisComponent in a BASIC macro and that gives you access to the interfaces and 
models and so forth needed to get the information or to do what you need to do.
- "PDF Export filter data" is the main section you'll need.  It includes 
information about all the PDF settings that can be used in the PropertyValue 
object "FilterData"  They're the same in Java as in BASIC.

The second page contains a Java example of someone setting almost any property 
possible for exporting a PDF:

http://forum.openoffice.org/en/forum/viewtopic.php?t=1804

This page helped me because, even after multiple readings, I still 
misunderstood (and didn't know it was a misunderstanding) one paragraph in the 
first linked page, so it clarified a major point for me.


About My Code: The code below is a macro that will export an ODT file as 
multiple PDFs - one PDF per page of the original document, all stored in a 
directory that is the same name as the original document's name but with "-PDF" 
instead of ".odt" at the end.  PDF File names are in the format of 
"Page-0001.pdf" with the page number always as 4 digits, with leading zeros.  
I've added a number of comments that should explain most of what's needed.  I 
don't know how to also include, here, the dialog box I use.  It has a text 
label that can be set to whatever you want and has a progress bar (we see how 
that's accessed in the code) and the progress bar is updated each time a page 
is done.

There are two issues with the progress bar.  The first is that I had to put in 
a 1 millisecond wait after it is updated, or it wouldn't update (I guess LO 
gives priority to running the macro code than in updating the GUI).  The other 
is that, on my dialog, I added a "Cancel" button, but I have two problems 
there.  One is that it doesn't seem to respond, and the other is that I wish I 
could pass a pointer to the progress bar so I can keep the dialog in my library 
and easily tell it, from any macro, what method to use when Cancel is clicked 
on.

Here is the source code:
-------------
REM  *****  BASIC  *****
REM **********************************************************
REM Export an ODT file from LibreOffice to multiple PDF files.
REM This creates one PDF file for each page of the document.
REM
REM This program can help in terms of teaching or examples for
REM several issues in BASIC macros:
REM    1) Adjusting settings for PDF Export
REM    2) Finding information about the document, such as the
REM       total number of pages
REM    3) Using a progress bar that updates during execution
REM       of a Macro
REM
REM
REM Copyright (C) 2013 by Hal Vaughan, [email protected]
REM **********************************************************

Sub ExportMultiPagePDF

'Specify thtat it load my dialogs - haven't tested in new LO builds,
' but in OpenOffice, if the libraries weren't specifically loaded, I'd
' get error codes
        DialogLibraries.LoadLibrary("HalLib")
        oDoc = ThisComponent
        
'We're going to save the multiple PDF files in a directory with the same name
' as the original document - but with "-PDF" added to it.  LO creates the
' directory automatically when saving the files, so that's one task we don't 
need
' to worry about.  If the document has not been saved, we exit.  If it has been,
' we get the URL, then remove the ".odt" and add "-PDF" to it.
'
'While there are other ways to check if a document is an odt file, since we 
' require that the document already be saved, it's easiest to just check the 
file
' extension.
        If Not oDoc.hasLocation() Then
                MsgBox "Cannot Export Multipage PDFs without first saving the 
file."
                Stop
        EndIf
        
'getPageCount (in this file) does the work of finding out how many pages
' there are in the document
        iTotal = getPageCount()
        sName = oDoc.getURL()
'       MsgBox "Frame Title: " + sName
        sExt = Right(sName, 4)
        If sExt <> ".odt" Then
                MsgBox "Unable to decode extension."
                Stop
        EndIf
        dirName = Left(sName, Len(sName) - 4) + "-PDF"

'Add a progress bar because this can take time on longer documents
        pbBar = Dialogs.EasyProgressBar("Converting to multiple PDFs", iTotal)
        
'Loop through each page, create a 4 digit number made out of the page
' number but with leading zeros so a directory listing will show the files
' in order.
'IMPORTANT: Note the "Wait 1" statemetn after updating the progress bar.
' Without this, the progress bar will not update (at least on OS X).  Apparently
' the GUI doesn't get time to update while the the macro is running, so a WAIT
' statement allows it to update
        For i = 1 to iTotal
                sFix = i
                sFix = "0000" + sFix
                sFix = Right(sFix, 4)
                fName = dirName + "/" + "Page-" + sFix + ".pdf"
                savePageAsPDF(fName, i)
                pbBar.ProgressValue = i
                Wait 1
        Next i

'Unceremonious exit.  The progress bar will complete and the dialog disappears.
' There's no real need to put up a dialog box and require a mouse click to to
' finish up.  It's just a pain to the user.

End Sub


'Get the number of pages from the document.
'
'Get the document properties, then look through the property names until we find
' "PageCount" and that's the number we need.
'No actual reason for going backwards through the elements that I can remember, 
but
' when I first wrote this functino I may have had a reason.
'Note that, in case of error, we set the PageCount to 0 by default and only 
change
' it if  the actual count is greater than -1
Function getPageCount()
        oProps = ThisComponent.getDocumentProperties()
        aStats = oProps.DocumentStatistics
REM Loop through the array of c.s.s.beans.NamedValue
        For i = uBound(aStats) to 0 Step -1
                x = aStats(i)
                If x.Name = "PageCount" Then Exit For
        Next
        getPageCount = 0
        if i > -1 then getPageCount = x.Value
End Function


'This is the part of this macro that was the most difficult to deal with, since 
it
' took a lot of online searching, using different terms, to find what amounted 
to
' the two or three sources I needed to tell me just what to do here.
'The first thing done is converting the page number to a page range.  That's not
' necessary, since the single page number is enough, but it's left here as a 
reminder
' that we're working with a page range string that will be parsed, so it could 
be
' something more complex, like "1,2,5,7-10,12-15"
'Next we need a property value to be passed as an argument to the storeToURL 
method
' within the document.  The first property MUST be "FilterName" with the 
"writer_pdf_Export"
' value. That's enough for a PDF export, but if you want to change any 
settings, then the
' second property MUST be named "FilterData" and is another PropteryValue 
ojbect that contains
' the settings for all the properties that we want to change from the default.  
In this case,
' we want to export only one page, so we set "PageRange" to the page number.
'Please note that this is a PropertyValue passed as a value WITHIN another 
PropertyValue object.
'It is not passed as a 3rd parameter, but as part of the 2nd paremeter.  (The 
wording on one page
' on this confused me and led to hours of research to clarify this.)
Sub SavePageAsPDF(fileName As String, pageNum As Integer)
        pRange = CStr(pageNum) + "-" + CStr(pageNum)
        
        Dim conversionProps(2) as new com.sun.star.beans.PropertyValue 
        conversionProps(0).Name = "FilterName" 
        conversionProps(0).Value = "writer_pdf_Export"
        
        Dim filterProps(1) as new com.sun.star.beans.PropertyValue 
        filterProps(0).Name = "PageRange"
        filterProps(0).Value = CStr(pageNum)
        
        conversionProps(1).Name = "FilterData"
        conversionProps(1).Value = filterProps
        
        ThisComponent.storeToURL(fileName, conversionProps)
End Sub

'Create a progress bar to display while a function is ongoing, so the user 
doesn't think
' things have frozen up.
'1st parameter is a string to use as a label, perhaps saying what is going on, 
and the
' 2nd parameter is how many steps there are to whatever is being done.  It 
returns the
' actual progress bar and all that is needed in other code is to use:
'
'    epBar = EasyProgressBar("Processing your stuff", 132)
'(and replace epBar with whatever name you want to use, the string with your 
label and
' the '132' with the number of steps your task will take.
'To set the progress bar to a position, do this:
'    epBar.ProgressValue = x
' (of course, use whatever variable names you want and 'x' will be the number 
of the
' completeted item)
'
'If you're using this code as an example, or to make your own macro, you need 
to use your
' on library name in place of "HalLib" and create a dialog with a text label 
named "TextInfo"
' and a progress bar named "ProgressBar".)
Function EasyProgressBar (Description As String, totalSteps As Integer) As 
Object
        DialogLibraries.LoadLibrary("HalLib")
        oDialog = createUnoDialog(DialogLibraries.HalLib.SimpleProgressBar)
        oDialog.setVisible(TRUE)
        oDialog.GetControl("TextInfo").Text = Description
        oDialog.GetControl("TextInfo").setVisible(TRUE)
        pbModel = oDialog.Model.ProgressBar
        pbModel.ProgressValueMin = 0
        pbModel.ProgressValueMax = totalSteps
        oDialog.getControl("ProgressBar").setVisible(TRUE)
        EasyProgressBar = pbModel
End Function

On Dec 27, 2012, at 6:48 PM, Hal Vaughan <[email protected]> wrote:

> I'm exporting ODT files to PDF, but I want to export only 1 page at a time, 
> so I'm using a BASIC macro to handle this.
> 
> I've been searching, but since somewhere around 3-4am EST, I have not been 
> able to access oooforum.org and most links lead to there.
> 
> I can't find examples elsewhere that show me how to export a PDF file from in 
> BASIC or how to specify, again, from BASIC, what pages to export.
> 
> Can anyone give me links for examples that are not on oooforum.org?  Or tell 
> me what classes I would be using for this so I can look them up in the IDL to 
> find out how to specify the page (or pages) to export and how to use the PDF 
> exporter?
> 
> 
> Thank you.
> 
> 
> 
> Hal

-- 
For unsubscribe instructions e-mail to: [email protected]
Problems? http://www.libreoffice.org/get-help/mailing-lists/how-to-unsubscribe/
Posting guidelines + more: http://wiki.documentfoundation.org/Netiquette
List archive: http://listarchives.libreoffice.org/global/users/
All messages sent to this list will be publicly archived and cannot be deleted

Reply via email to