Difference between revisions of "Python/PrintPagesRanges"

From Apache OpenOffice Wiki
Jump to: navigation, search
m (Load print ranges)
m (Process of the script)
 
(5 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
{{DISPLAYTITLE:Printing selected sheets and ranges}}
 
{{DISPLAYTITLE:Printing selected sheets and ranges}}
This script was published by Villeroy at the [http://forum.openoffice.org/en/forum/viewtopic.php?f=21&t=62054 Code Snippets Forum].
+
This script was published by Villeroy at the [https://forum.openoffice.org/en/forum/viewtopic.php?f=21&t=62054 Code Snippets Forum].
 
;Villeroy quote:
 
;Villeroy quote:
 
:''The attached Python code provides 2 routines. One prints the current selection of (multiple) cell range(s), the other one prints the used ranges of the selected sheet(s).''
 
:''The attached Python code provides 2 routines. One prints the current selection of (multiple) cell range(s), the other one prints the used ranges of the selected sheet(s).''
Line 101: Line 101:
  
 
== Process of the script ==
 
== Process of the script ==
The script perform the following tasks:
+
The script performs the following tasks:
# Loop through the sheets collection and load the print ranges them in a variable.
+
# Loop through the sheets collection and load the print ranges then in a variable.
 
# Remove them
 
# Remove them
 
# Change the selected ranges into print ranges
 
# Change the selected ranges into print ranges
Line 109: Line 109:
 
# Restore the original print ranges
 
# Restore the original print ranges
  
The script first create the functions we will perform on the '''printSomething()''' function. We generate 5 functions that will manipulate the Print Ranges and finally call them up on the final function.
+
The script first creates the functions we will perform on the '''printSomething()''' function. We generate 5 functions that will manipulate the Print Ranges and finally call them up on the final function.
  
 
== Calling the API ==
 
== Calling the API ==
We make aware that our Python code will use the UNO API by importing the Module UNO and RuntimeException. The RuntimeException depends from the uno module. It help us signal an error, which was not covered by the interface method specification. Meaning that we will use this to have extra error handling features.
+
We make aware that our Python code will use the UNO API by importing the Module UNO and RuntimeException. The RuntimeException depends from the uno module. It helps us signal an error, which was not covered by the interface method specification. Meaning that we will use this to have extra error handling features.
 
<syntaxhighlight lang="Python">
 
<syntaxhighlight lang="Python">
 
import uno
 
import uno
Line 133: Line 133:
 
== Clear print ranges ==
 
== Clear print ranges ==
 
This function reset the cell range using the '''createEnumeration()''' function and doing a loop until the end.
 
This function reset the cell range using the '''createEnumeration()''' function and doing a loop until the end.
<source lang="Python">
+
<syntaxhighlight lang="Python">
 
def clearPrintAreas(doc):
 
def clearPrintAreas(doc):
 
     '''remove all print areas from a Calc document'''
 
     '''remove all print areas from a Calc document'''
Line 139: Line 139:
 
     while esh.hasMoreElements():
 
     while esh.hasMoreElements():
 
         sh = esh.nextElement()
 
         sh = esh.nextElement()
         sh.setPrintAreas(tuple())</source>
+
         sh.setPrintAreas(tuple())
 +
</syntaxhighlight>
  
 
== Create print ranges ==
 
== Create print ranges ==
Line 152: Line 153:
 
the '''getUsedAddress()''' function.
 
the '''getUsedAddress()''' function.
  
<source lang="Python">
+
<syntaxhighlight lang="Python">
 
def getPrintAreasDict(doc):
 
def getPrintAreasDict(doc):
 
     '''return a dict of sheet indices with print areas'''
 
     '''return a dict of sheet indices with print areas'''
Line 168: Line 169:
 
         if bWholeSheet:
 
         if bWholeSheet:
 
             v = (getUsedAddress(sh),)
 
             v = (getUsedAddress(sh),)
         sh.setPrintAreas(v)</source>
+
         sh.setPrintAreas(v)
 +
</syntaxhighlight>
  
 
== Print as PDF ==
 
== Print as PDF ==
Line 176: Line 178:
 
Then we use the '''unohelper.systemPathToFile()''' and load  
 
Then we use the '''unohelper.systemPathToFile()''' and load  
 
the f variable.
 
the f variable.
<source lang="Python">
+
<syntaxhighlight lang="Python">
 
def getTmpURL():
 
def getTmpURL():
 
     import unohelper, os
 
     import unohelper, os
 
     f = os.tmpnam() +'.pdf'
 
     f = os.tmpnam() +'.pdf'
     return unohelper.systemPathToFileUrl(f)</source>
+
     return unohelper.systemPathToFileUrl(f)
 +
</syntaxhighlight>
  
 
== Clear the ranges ==
 
== Clear the ranges ==
Line 207: Line 210:
 
* Instantiating the service <idl>com.sun.star.sheet.SheetCellRange</idl>
 
* Instantiating the service <idl>com.sun.star.sheet.SheetCellRange</idl>
 
* We verify that the cell range is defined otherwise use an aditional function '''queryIntersection()'''
 
* We verify that the cell range is defined otherwise use an aditional function '''queryIntersection()'''
* We backup the print area with the functions '''getPrintAreaDict()''' and '''getDictFromAddresses()'''
+
* We back up the print area with the functions '''getPrintAreaDict()''' and '''getDictFromAddresses()'''
 
* We dump the information on our temporary file and fill the properties using <idl>com.sun.star.beans.PropertyValue</idl>
 
* We dump the information on our temporary file and fill the properties using <idl>com.sun.star.beans.PropertyValue</idl>
 
* We finalize by using the XPrint service and provide the '''setPrintAreasByDict()''' and supply them with the print areas
 
* We finalize by using the XPrint service and provide the '''setPrintAreasByDict()''' and supply them with the print areas
<source lang="Python">
+
<syntaxhighlight lang="Python">
 
def printSomething(bWholeSheet):
 
def printSomething(bWholeSheet):
 
     doc = XSCRIPTCONTEXT.getDocument()    sel = doc.getCurrentSelection()
 
     doc = XSCRIPTCONTEXT.getDocument()    sel = doc.getCurrentSelection()
Line 223: Line 226:
 
         raise(Exception, 'NO RANGE SELECTION')
 
         raise(Exception, 'NO RANGE SELECTION')
  
     # backup current print areas
+
     # back up current print areas
 
     d1 = getPrintAreasDict(doc)
 
     d1 = getPrintAreasDict(doc)
 
     clearPrintAreas(doc)
 
     clearPrintAreas(doc)
Line 235: Line 238:
 
     doc.com_sun_star_view_XPrintable_print((p,))
 
     doc.com_sun_star_view_XPrintable_print((p,))
 
     clearPrintAreas(doc)
 
     clearPrintAreas(doc)
     setPrintAreasByDict(doc, d1, False)</source>
+
     setPrintAreasByDict(doc, d1, False)
 +
</syntaxhighlight>
 +
 
 
[[Category:Python]]
 
[[Category:Python]]

Latest revision as of 13:57, 15 May 2021

This script was published by Villeroy at the Code Snippets Forum.

Villeroy quote
The attached Python code provides 2 routines. One prints the current selection of (multiple) cell range(s), the other one prints the used ranges of the selected sheet(s).

Original code

import uno
from com.sun.star.uno import RuntimeException
 
def getUsedAddress(oSheet):
    '''com.sun.star.table.CellRangeAddress of a sheet's used range'''
    oRg = oSheet.createCursor()
    oRg.gotoStartOfUsedArea(False)
    oRg.gotoEndOfUsedArea(True)
    return oRg.getRangeAddress()
 
def clearPrintAreas(doc):
    '''remove all print areas from a Calc document'''
    esh = doc.Sheets.createEnumeration()
    while esh.hasMoreElements():
        sh = esh.nextElement()
        sh.setPrintAreas(tuple())
 
def getPrintAreasDict(doc):
    '''return a dict of sheet indices with print areas'''
    d = {}
    esh = doc.Sheets.createEnumeration()
    while esh.hasMoreElements():
        sh = esh.nextElement()
        n = sh.RangeAddress.Sheet
        d[n]= sh.getPrintAreas()
    return d
 
def setPrintAreasByDict(doc, d, bWholeSheet):
    for k,v in d.items():
        sh = doc.Sheets.getByIndex(k)
        if bWholeSheet:
            v = (getUsedAddress(sh),)
        sh.setPrintAreas(v)
 
def getTmpURL():
    import unohelper, os
    f = os.tmpnam() +'.pdf'
    return unohelper.systemPathToFileUrl(f)
 
def getDictFromAddresses(tpla):
    '''Split tuple of addresses into dict of sheet indices.'''
    d = {}
    for i in tpla:
        ish = i.Sheet
        if not d.has_key(ish):
            d[ish] = [i,]
        else:
            d[ish].append(i)
 
    for k,v in d.items():
        d[k] = tuple(v)
 
    return d
 
def printSelectedCells():
    '''Print current selection of (multiple) cell range(s)'''
    printSomething(False)
 
def printSelectedSheets():
    '''Print used ranges of currently selected sheets'''
    printSomething(True)
 
def printSomething(bWholeSheet):
    doc = XSCRIPTCONTEXT.getDocument()
    sel = doc.getCurrentSelection()
 
    # Let's support c.s.s.sheet.SheetCellRanges collection.
    # The intersection of a range with its own address
    # gives a collection having that single range
    if sel.supportsService('com.sun.star.sheet.SheetCellRange'):
        sel = sel.queryIntersection(sel.getRangeAddress())
    elif sel.supportsService('com.sun.star.sheet.SheetCellRanges'):
        a = sel.getRangeAddresses()
    else:
        raise(Exception, 'NO RANGE SELECTION')
 
    # back up current print areas
    d1 = getPrintAreasDict(doc)
    clearPrintAreas(doc)
 
    d2 = getDictFromAddresses(a)
    setPrintAreasByDict(doc, d2, bWholeSheet)
 
    p = uno.createUnoStruct('com.sun.star.beans.PropertyValue')
    p.Name = 'FileName'
    p.Value = getTmpURL()
    doc.com_sun_star_view_XPrintable_print((p,))
 
    clearPrintAreas(doc)
    setPrintAreasByDict(doc, d1, False)
 
g_exportedScripts = printSelectedCells, printSelectedSheets,

Process of the script

The script performs the following tasks:

  1. Loop through the sheets collection and load the print ranges then in a variable.
  2. Remove them
  3. Change the selected ranges into print ranges
  4. Store the ranges into a temporary PDF
  5. Clear the print ranges
  6. Restore the original print ranges

The script first creates the functions we will perform on the printSomething() function. We generate 5 functions that will manipulate the Print Ranges and finally call them up on the final function.

Calling the API

We make aware that our Python code will use the UNO API by importing the Module UNO and RuntimeException. The RuntimeException depends from the uno module. It helps us signal an error, which was not covered by the interface method specification. Meaning that we will use this to have extra error handling features.

import uno
from com.sun.star.uno import RuntimeException

Load print ranges

We start by grabbing the area from the Calc page using the com.sun.star.table.CellRangeAddress, establish the start and end of the used area and return the total range of cells.

def getUsedAddress(oSheet):
    '''com.sun.star.table.CellRangeAddress of a sheet's used range'''
    oRg = oSheet.createCursor()
    oRg.gotoStartOfUsedArea(False)
    oRg.gotoEndOfUsedArea(True)
    return oRg.getRangeAddress()

Clear print ranges

This function reset the cell range using the createEnumeration() function and doing a loop until the end.

def clearPrintAreas(doc):
    '''remove all print areas from a Calc document'''
    esh = doc.Sheets.createEnumeration()
    while esh.hasMoreElements():
        sh = esh.nextElement()
        sh.setPrintAreas(tuple())

Create print ranges

Here we use two functions:

  • Get the print area with a dictionary
  • Set the print area with a dictionary

We generate a dictionary then we load it with a createEnumeration() and a loop to go to the next element within the Range on the sheet.

For the setting the print area you do a getByIndex() a conditional that goes through the dictionary in d and use the getUsedAddress() function.

def getPrintAreasDict(doc):
    '''return a dict of sheet indices with print areas'''
    d = {}
    esh = doc.Sheets.createEnumeration()
    while esh.hasMoreElements():
        sh = esh.nextElement()
        n = sh.RangeAddress.Sheet
        d[n]= sh.getPrintAreas()
    return d
 
def setPrintAreasByDict(doc, d, bWholeSheet):
    for k,v in d.items():
        sh = doc.Sheets.getByIndex(k)
        if bWholeSheet:
            v = (getUsedAddress(sh),)
        sh.setPrintAreas(v)

Print as PDF

We use this function to drop the data information into a temporary file. We generate the name into os.tmpnam() and add the .pdf extension, loading it into f. Then we use the unohelper.systemPathToFile() and load the f variable.

def getTmpURL():
    import unohelper, os
    f = os.tmpnam() +'.pdf'
    return unohelper.systemPathToFileUrl(f)

Clear the ranges

We use the tuple into a function that will go through it and pass it to a dictionary which will separate the value and the index.

def getDictFromAddresses(tpla):
    '''Split tuple of addresses into dict of sheet indices.'''
    d = {}
    for i in tpla:
        ish = i.Sheet
        if not d.has_key(ish):
            d[ish] = [i,]
        else:
            d[ish].append(i)
 
    for k,v in d.items():
        d[k] = tuple(v)
 
    return d

Making it all work

For these steps we first call the document, and the service to manipulate the Cell Ranges within. Then we execute the functions we previously wrote.

We could subdivide this script into:

  • Getting the current document
  • Instantiating the service com.sun.star.sheet.SheetCellRange
  • We verify that the cell range is defined otherwise use an aditional function queryIntersection()
  • We back up the print area with the functions getPrintAreaDict() and getDictFromAddresses()
  • We dump the information on our temporary file and fill the properties using com.sun.star.beans.PropertyValue
  • We finalize by using the XPrint service and provide the setPrintAreasByDict() and supply them with the print areas
def printSomething(bWholeSheet):
    doc = XSCRIPTCONTEXT.getDocument()    sel = doc.getCurrentSelection()
    # Let's support c.s.s.sheet.SheetCellRanges collection.
    # The intersection of a range with its own address
    # gives a collection having that single range
    if sel.supportsService('com.sun.star.sheet.SheetCellRange'):
        sel = sel.queryIntersection(sel.getRangeAddress())
    elif sel.supportsService('com.sun.star.sheet.SheetCellRanges'):
        a = sel.getRangeAddresses()
    else:
        raise(Exception, 'NO RANGE SELECTION')
 
    # back up current print areas
    d1 = getPrintAreasDict(doc)
    clearPrintAreas(doc)
    d2 = getDictFromAddresses(a)
    setPrintAreasByDict(doc, d2, bWholeSheet)
 
    p = uno.createUnoStruct('com.sun.star.beans.PropertyValue')
    p.Name = 'FileName'
    p.Value = getTmpURL()
 
    doc.com_sun_star_view_XPrintable_print((p,))
    clearPrintAreas(doc)
    setPrintAreasByDict(doc, d1, False)
Personal tools