Difference between revisions of "Python/PrintPagesRanges"

From Apache OpenOffice Wiki
Jump to: navigation, search
(Print as PDF)
(Clear the ranges)
Line 174: Line 174:
  
 
== Clear the ranges ==
 
== 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.
 
<source lang="Python">
 
<source lang="Python">
 
def getDictFromAddresses(tpla):
 
def getDictFromAddresses(tpla):

Revision as of 11:00, 29 August 2013

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 perform the following tasks:

  1. Loop through the sheets collection and load the print ranges them 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

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 area and return the total area.

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

Restore print ranges

 
Personal tools