Textboxes in Macro Created in Reverse Order and Multiple Textboxes Per Page

Hi everyone,

I’m working on a LibreOffice Writer macro that reads lines from a text file and creates a separate textbox for each line on a new page. However, I’m facing two issues:

  1. Reverse Order: The textboxes are being created in reverse order. For example, the first line of text from the file appears in the last textbox, and the last line of text appears in the first textbox.
  2. Multiple Textboxes Per Page: Despite my intention to have one textbox per page, sometimes multiple textboxes are being added to a single page.

What I’m Trying to Do:

  • I want to create a new page for each line from the text file and insert one textbox per page in the correct order.
Sub CreateDocumentWithFormTextboxes()
    Dim oDoc As Object
    Dim oText As Object
    Dim oCursor As Object
    Dim oDrawPage As Object
    Dim oTextBox As Object
    Dim sTextFile As String
    Dim sLine As String
    Dim oTextInputStream As Object
    Dim oFileAccess As Object
    Dim iNumPages As Integer
    Dim aPosition As New com.sun.star.awt.Point
    Dim aSize As New com.sun.star.awt.Size
    Dim i As Integer

    ' Get the active document
    oDoc = ThisComponent
    oText = oDoc.Text
    oCursor = oText.createTextCursor()

    ' Prompt user for input parameters
    iNumPages = CInt(InputBox("Enter the number of pages (even number):", "Number of Pages"))
    sTextFile = InputBox("Enter the path to the text file:", "Text File Path")
    
    ' Validate inputs
    If iNumPages < 1 Or iNumPages Mod 2 <> 0 Then
        MsgBox "The number of pages must be an even number greater than 0."
        Exit Sub
    End If

    If Dir(sTextFile) = "" Then
        MsgBox "Text file not found."
        Exit Sub
    End If

    ' Create FileAccess service for file operations
    oFileAccess = createUnoService("com.sun.star.ucb.SimpleFileAccess")
    oTextInputStream = createUnoService("com.sun.star.io.TextInputStream")
    oTextInputStream.setInputStream(oFileAccess.openFileRead(ConvertToURL(sTextFile)))

    ' Loop to create pages and insert text from file
    For i = 1 To iNumPages
        ' Read the next line from the text file
        If Not oTextInputStream.isEOF() Then
            sLine = oTextInputStream.readLine()
        Else
            Exit For  ' Exit loop if no more lines
        End If

        ' Move the cursor to the end of the document and insert a paragraph break
        oCursor.gotoEnd(False)
        oText.insertControlCharacter(oCursor, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False)
        oCursor.gotoEnd(False)

        ' Insert a page break to start a new page for the next textbox
        If i > 1 Then
            oText.insertControlCharacter(oCursor, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False)
            oCursor.BreakType = com.sun.star.style.BreakType.PAGE_BEFORE
            oCursor.gotoEnd(False) ' Move cursor to the end after inserting the page break
        End If

        ' Refresh the draw page to ensure it applies to the new page context
        oDrawPage = oDoc.DrawPage

        ' Create and configure the textbox
        oTextBox = oDoc.createInstance("com.sun.star.drawing.TextShape")
        oTextBox.TextAutoGrowHeight = False
        oTextBox.TextAutoGrowWidth = False
        oTextBox.FillStyle = com.sun.star.drawing.FillStyle.SOLID
        oTextBox.FillColor = RGB(211, 211, 211)
        oTextBox.FillTransparence = 20
        oTextBox.LineStyle = com.sun.star.drawing.LineStyle.SOLID
        oTextBox.LineColor = RGB(0, 0, 0)
        oTextBox.LineWidth = 20
        oTextBox.TextVerticalAdjust = com.sun.star.drawing.TextVerticalAdjust.CENTER

        ' Set textbox size and position
        aSize.Width = 18000  ' Example width, adjust as needed
        aSize.Height = 4000  ' Example height, adjust as needed
        aPosition.X = 1000   ' Example left margin, adjust as needed
        aPosition.Y = 1000   ' Example top margin, adjust as needed
        oTextBox.setSize(aSize)
        oTextBox.setPosition(aPosition)

        ' Add the textbox to the current page's draw page
        oDrawPage.add(oTextBox)

        ' Set text alignment and add the line
        Dim oTextCursor As Object
        oTextCursor = oTextBox.createTextCursor()
        oTextCursor.CharHeight = 20
        oTextCursor.ParaAdjust = com.sun.star.style.ParagraphAdjust.CENTER
        oTextBox.String = sLine  ' Set the text directly in the text box
    Next i

    ' Close the input stream
    oTextInputStream.closeInput()

    MsgBox "Text inserted into textboxes successfully."
End Sub

This demo code uses:

Note that created this way (as opposed to creation of a purely graphical object in drawing page), you define the anchoring and positioning correctly.
Note also, that the cursor is not really needed - any range would do in the call to insertTextContent.

Sub insert_textframe_at_cursor()
 doc = ThisComponent
 pos = doc.CurrentSelection.getByIndex(0).End

 textframe = doc.createInstance("com.sun.star.text.TextFrame")
 textframe.AnchorType = com.sun.star.text.TextContentAnchorType.AT_PARAGRAPH
 textframe.HoriOrient = com.sun.star.text.HoriOrientation.NONE
 textframe.HoriOrientRelation = com.sun.star.text.RelOrientation.PAGE_LEFT
 textframe.HoriOrientPosition = 11000
 textframe.VertOrient = com.sun.star.text.VertOrientation.NONE
 textframe.VertOrientRelation = com.sun.star.text.RelOrientation.PAGE_FRAME
 textframe.VertOrientPosition = 12000
 textframe.Width = 2500
 textframe.Height = 2500

 pos.Text.insertTextContent(pos, textframe, False)
 textframe.Text.String = "abc"
End Sub

Thanks It really helped!