Add remove, save, clone images
This commit is contained in:
parent
70e1933537
commit
b8954d7ade
|
@ -106,4 +106,18 @@ Agrega una nueva forma (un rectángulo) y la devuelve.
|
|||
app.debug(forma)
|
||||
```
|
||||
|
||||
De forma predeterminada la posición será a 1 cm en Y y X y de 3 cm de ancho y alto. Estos valores se pueden modificar al crear la forma. Todas las unidades en milésimas de centímetro.
|
||||
|
||||
```py
|
||||
opciones = dict(
|
||||
Name = 'mi_rectangulo_1',
|
||||
Width = 5000,
|
||||
Height = 2000,
|
||||
X = 3000,
|
||||
Y = 1000,
|
||||
)
|
||||
|
||||
forma = formas.add('Rectangle', opciones)
|
||||
```
|
||||
|
||||
<br>
|
|
@ -1,7 +1,202 @@
|
|||
## Propiedades
|
||||
|
||||
Todas las unidades en milésimas de centímetro.
|
||||
|
||||
---
|
||||
|
||||
### **anchor**
|
||||
|
||||
Anclaje de la forma, por default se agrega a la página.
|
||||
|
||||
#### Anclaje a una celda
|
||||
|
||||
```py
|
||||
celda = hoja['A1']
|
||||
forma.anchor = celda
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### **height**
|
||||
|
||||
Alto de la forma.
|
||||
|
||||
```py
|
||||
forma.height = 2000
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### **name**
|
||||
|
||||
Devuelve o establece el nombre de la forma.
|
||||
|
||||
```py
|
||||
app.debug(forma.name)
|
||||
forma.name = 'otro_rectangulo'
|
||||
app.debug(forma.name)
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### **obj**
|
||||
|
||||
**Solo lectura.** Devuelve el objeto original pyUNO.
|
||||
|
||||
```py
|
||||
objeto = forma.obj
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### **possize**
|
||||
|
||||
Devuelve o establece la posición y el tamaño de la forma.
|
||||
|
||||
```py
|
||||
posicion_y_tamaño = dict(
|
||||
Width = 5000,
|
||||
Height = 2000,
|
||||
X = 3000,
|
||||
Y = 1000,
|
||||
)
|
||||
forma.possize = posicion_y_tamaño
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### **properties**
|
||||
|
||||
Devuelve un diccionario con todas las propiedades de la forma.
|
||||
|
||||
```py
|
||||
for p, v in forma.properties.items():
|
||||
app.debug(f'{p} = {v}')
|
||||
```
|
||||
|
||||
Al establecer solo aplica las que se pasen en un diccionario.
|
||||
|
||||
```py
|
||||
propiedades = dict(
|
||||
LineColor = app.color('red'),
|
||||
LineWidth = 100,
|
||||
)
|
||||
forma.properties = propiedades
|
||||
```
|
||||
|
||||
!!! tip "Atención"
|
||||
|
||||
Aquí hay que usar los nombres "originales" de las propiedades de la forma en el API de LibreOffice.
|
||||
|
||||
<br>
|
||||
|
||||
### **resize_with_cell**
|
||||
|
||||
Si el tamaño de la forma cambia con la celda, solo cuando el anclaje es a una celda.
|
||||
|
||||
```py
|
||||
forma.resize_with_cell = True
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### **shape_type**
|
||||
|
||||
**Solo lectura**. Devuelve el tipo de forma.
|
||||
|
||||
```py
|
||||
app.debug(forma.shape_type)
|
||||
```
|
||||
|
||||
```
|
||||
24/04/2023 13:55:32 - DEBUG - com.sun.star.drawing.RectangleShape
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### **width**
|
||||
|
||||
Ancho de la forma.
|
||||
|
||||
```py
|
||||
forma.width = 6000
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### **x**
|
||||
|
||||
Posición en el eje X.
|
||||
|
||||
```py
|
||||
forma.x = 5000
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### **y**
|
||||
|
||||
Posición en el eje Y.
|
||||
|
||||
```py
|
||||
forma.y = 1000
|
||||
```
|
||||
|
||||
## Métodos
|
||||
|
||||
---
|
||||
---
|
||||
|
||||
### **clone**
|
||||
|
||||
Clona la imagen en la misma hoja.
|
||||
|
||||
```py
|
||||
imagen.clone()
|
||||
```
|
||||
|
||||
Clona la imagen en otra hoja.
|
||||
|
||||
```py
|
||||
imagen.clone(doc['Hoja5'].draw_page)
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### **remove**
|
||||
|
||||
Eliminar la forma.
|
||||
|
||||
```py
|
||||
forma.remove()
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### **save**
|
||||
|
||||
Guarda la imagen en disco. Si no se pasa ningún argumento, toma la ruta del documento y el nombre de la imagen.
|
||||
|
||||
!!! tip inline end "Atención"
|
||||
|
||||
El documento ya debe estar guardado
|
||||
|
||||
```py
|
||||
imagen.save()
|
||||
```
|
||||
|
||||
Podemos pasar una ruta diferente, seguira tomando el nombre de la imagen.
|
||||
|
||||
```py
|
||||
ruta = '/home/elmau/imagenes'
|
||||
imagen.save(ruta)
|
||||
```
|
||||
|
||||
Podemos cambiar el nombre.
|
||||
|
||||
```py
|
||||
ruta = '/home/elmau/imagenes'
|
||||
name = f'{hoja.name}_nuevo_nombre'
|
||||
imagen.save(path, name)
|
||||
```
|
||||
|
||||
<br>
|
|
@ -0,0 +1,155 @@
|
|||
---
|
||||
title: Índice
|
||||
---
|
||||
|
||||
# Ejemplos reales de uso
|
||||
|
||||
---
|
||||
|
||||
## Calc
|
||||
|
||||
---
|
||||
|
||||
### Solicitar precios
|
||||
|
||||
Consultar datos en json a una página web y vaciarlos en una hoja.
|
||||
|
||||
=== "EasyMacro"
|
||||
|
||||
```py
|
||||
import easymacro as app
|
||||
|
||||
def obtener_precios():
|
||||
URL = 'https://api.binance.com/api/v3/ticker/price'
|
||||
respuesta = app.url.get(URL)
|
||||
if respuesta.status_code == 200:
|
||||
datos = respuesta.json()
|
||||
app.active.active['A1'].dict = datos
|
||||
return
|
||||
```
|
||||
|
||||
=== "Sin EasyMacro"
|
||||
|
||||
```py
|
||||
import uno
|
||||
import json
|
||||
from urllib import request
|
||||
|
||||
def obtener_precios():
|
||||
URL = 'https://api.binance.com/api/v3/ticker/price'
|
||||
data = json.loads(request.urlopen(URL).read().decode())
|
||||
|
||||
doc = XSCRIPTCONTEXT.getDocument()
|
||||
sheet = doc.CurrentController.ActiveSheet
|
||||
|
||||
sheet[0,0].String = 'symbol'
|
||||
sheet[0,1].String = 'price'
|
||||
|
||||
for i, row in enumerate(data):
|
||||
sheet[i + 1,0].String = row['symbol']
|
||||
sheet[i + 1,1].Value = float(row['price'])
|
||||
|
||||
return
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### Clonar imagenes
|
||||
|
||||
Clonar todas las imagenes de una hoja a otra.
|
||||
|
||||
=== "EasyMacro"
|
||||
|
||||
```py
|
||||
doc = app.active
|
||||
for image in doc[0].dp:
|
||||
if image.is_image:
|
||||
image.clone(doc[1].dp)
|
||||
```
|
||||
|
||||
=== "Sin EasyMacro"
|
||||
|
||||
```py
|
||||
import uno
|
||||
import io
|
||||
import unohelper
|
||||
from com.sun.star.io import IOException, XOutputStream
|
||||
from com.sun.star.beans import PropertyValue
|
||||
|
||||
|
||||
CTX = uno.getComponentContext()
|
||||
SM = CTX.getServiceManager()
|
||||
|
||||
|
||||
class LOShape():
|
||||
|
||||
def __init__(self, shape):
|
||||
self._shape = shape
|
||||
|
||||
class OutputStream(unohelper.Base, XOutputStream):
|
||||
|
||||
def __init__(self):
|
||||
self._buffer = b''
|
||||
self.closed = 0
|
||||
|
||||
@property
|
||||
def buffer(self):
|
||||
return self._buffer
|
||||
|
||||
def closeOutput(self):
|
||||
self.closed = 1
|
||||
|
||||
def writeBytes(self, seq):
|
||||
if seq.value:
|
||||
self._buffer = seq.value
|
||||
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
def clone_image(self, doc, to_sheet):
|
||||
stream = self._shape.GraphicStream
|
||||
buffer = self.OutputStream()
|
||||
size, data = stream.readBytes(buffer, stream.available())
|
||||
|
||||
stream = SM.createInstanceWithContext('com.sun.star.io.SequenceInputStream', CTX)
|
||||
stream.initialize((data,))
|
||||
|
||||
image = doc.createInstance('com.sun.star.drawing.GraphicObjectShape')
|
||||
gp = SM.createInstance('com.sun.star.graphic.GraphicProvider')
|
||||
properties = (PropertyValue(Name='InputStream', Value=stream),)
|
||||
image.Graphic = gp.queryGraphic(properties)
|
||||
to_sheet.DrawPage.add(image)
|
||||
image.Size = self._shape.Size
|
||||
image.Position = self._shape.Position
|
||||
return
|
||||
|
||||
def clone_shape(self, doc, to_sheet):
|
||||
for p in self._shape.CustomShapeGeometry:
|
||||
if p.Name == 'Type':
|
||||
type_shape = p.Value.title()
|
||||
|
||||
service = f'com.sun.star.drawing.{type_shape}Shape'
|
||||
shape = doc.createInstance(service)
|
||||
shape.Size = self._shape.Size
|
||||
shape.Position = self._shape.Position
|
||||
to_sheet.DrawPage.add(shape)
|
||||
return
|
||||
|
||||
|
||||
def main():
|
||||
IMAGE = 'com.sun.star.drawing.GraphicObjectShape'
|
||||
SHAPE = 'com.sun.star.drawing.CustomShape'
|
||||
|
||||
doc = XSCRIPTCONTEXT.getDocument()
|
||||
source = doc.CurrentController.ActiveSheet
|
||||
target = doc.Sheets[1]
|
||||
|
||||
for shape in source.DrawPage:
|
||||
s = LOShape(shape)
|
||||
if shape.ShapeType == IMAGE:
|
||||
s.clone_image(doc, target)
|
||||
elif shape.ShapeType == SHAPE:
|
||||
s.clone_shape(doc, tar
|
||||
```
|
||||
|
||||
<br>
|
|
@ -32,6 +32,8 @@ nav:
|
|||
- Página de dibujo:
|
||||
- dp/drawpage.md
|
||||
- Formas: dp/shapes.md
|
||||
- Ejemplos de uso:
|
||||
- examples/index.md
|
||||
theme:
|
||||
name: material
|
||||
locale: es
|
||||
|
@ -53,7 +55,8 @@ markdown_extensions:
|
|||
pygments_lang_class: true
|
||||
- pymdownx.inlinehilite
|
||||
- pymdownx.snippets
|
||||
- pymdownx.superfences
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
#~ extra:
|
||||
#~ alternate:
|
||||
#~ - name: Español
|
||||
|
|
|
@ -1,51 +1,11 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import uno
|
||||
import unohelper
|
||||
from com.sun.star.io import IOException, XOutputStream
|
||||
from .easymain import (log,
|
||||
BaseObject, LOMain, Paths,
|
||||
dict_to_property, create_instance
|
||||
)
|
||||
|
||||
|
||||
class IOStream(object):
|
||||
"""Classe for input/output stream"""
|
||||
|
||||
class OutputStream(unohelper.Base, XOutputStream):
|
||||
|
||||
def __init__(self):
|
||||
self._buffer = b''
|
||||
self.closed = 0
|
||||
|
||||
@property
|
||||
def buffer(self):
|
||||
return self._buffer
|
||||
|
||||
def closeOutput(self):
|
||||
self.closed = 1
|
||||
|
||||
def writeBytes(self, seq):
|
||||
if seq.value:
|
||||
self._buffer = seq.value
|
||||
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def buffer(cls):
|
||||
return io.BytesIO()
|
||||
|
||||
@classmethod
|
||||
def input(cls, buffer):
|
||||
service = 'com.sun.star.io.SequenceInputStream'
|
||||
stream = create_instance(service, True)
|
||||
stream.initialize((uno.ByteSequence(buffer.getvalue()),))
|
||||
return stream
|
||||
|
||||
@classmethod
|
||||
def output(cls):
|
||||
return cls.OutputStream()
|
||||
from .easyuno import IOStream
|
||||
|
||||
|
||||
class LODocument(BaseObject):
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from pathlib import Path
|
||||
from com.sun.star.awt import Size, Point
|
||||
|
||||
from .easymain import (
|
||||
|
@ -228,7 +229,7 @@ class LODrawPage(BaseObject):
|
|||
|
||||
image = self._create_instance('com.sun.star.drawing.GraphicObjectShape')
|
||||
if isinstance(path, str):
|
||||
image.GraphicURL = _P.to_url(path)
|
||||
image.GraphicURL = Path(path).as_uri()
|
||||
else:
|
||||
gp = create_instance('com.sun.star.graphic.GraphicProvider')
|
||||
stream = IOStream.input(path)
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from com.sun.star.awt import Size, Point
|
||||
from .easymain import BaseObject, set_properties
|
||||
from .easymain import BaseObject, Paths, create_instance, dict_to_property, set_properties
|
||||
from .easyuno import IOStream, get_input_stream
|
||||
|
||||
|
||||
class LOShapes(object):
|
||||
|
@ -43,6 +44,10 @@ class LOShapes(object):
|
|||
|
||||
class LOShape(BaseObject):
|
||||
IMAGE = 'com.sun.star.drawing.GraphicObjectShape'
|
||||
MIME_TYPE = {
|
||||
'image/png': 'png',
|
||||
'image/jpeg': 'jpg',
|
||||
}
|
||||
|
||||
def __init__(self, obj):
|
||||
self._obj = obj
|
||||
|
@ -52,10 +57,12 @@ class LOShape(BaseObject):
|
|||
|
||||
@property
|
||||
def obj(self):
|
||||
"""Get original UNO object"""
|
||||
return self._obj
|
||||
|
||||
@property
|
||||
def anchor(self):
|
||||
"""Get anchor object"""
|
||||
return self.obj.Anchor
|
||||
@anchor.setter
|
||||
def anchor(self, obj):
|
||||
|
@ -66,6 +73,7 @@ class LOShape(BaseObject):
|
|||
|
||||
@property
|
||||
def resize_with_cell(self):
|
||||
"""If resize with cell"""
|
||||
return self.obj.ResizeWithCell
|
||||
@resize_with_cell.setter
|
||||
def resize_with_cell(self, value):
|
||||
|
@ -74,8 +82,7 @@ class LOShape(BaseObject):
|
|||
|
||||
@property
|
||||
def properties(self):
|
||||
# ~ properties = self.obj.PropertySetInfo.Properties
|
||||
# ~ data = {p.Name: getattr(self.obj, p.Name) for p in properties}
|
||||
"""Get all properties"""
|
||||
data = self.obj.PropertySetInfo.Properties
|
||||
keys = [p.Name for p in data]
|
||||
values = self.obj.getPropertyValues(keys)
|
||||
|
@ -87,10 +94,12 @@ class LOShape(BaseObject):
|
|||
|
||||
@property
|
||||
def shape_type(self):
|
||||
"""Get type shape"""
|
||||
return self.obj.ShapeType
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Get name"""
|
||||
return self.obj.Name
|
||||
@name.setter
|
||||
def name(self, value):
|
||||
|
@ -114,6 +123,7 @@ class LOShape(BaseObject):
|
|||
|
||||
@property
|
||||
def width(self):
|
||||
"""Width of shape"""
|
||||
s = self.obj.Size
|
||||
return s.Width
|
||||
@width.setter
|
||||
|
@ -124,6 +134,7 @@ class LOShape(BaseObject):
|
|||
|
||||
@property
|
||||
def height(self):
|
||||
"""Height of shape"""
|
||||
s = self.obj.Size
|
||||
return s.Height
|
||||
@height.setter
|
||||
|
@ -137,6 +148,7 @@ class LOShape(BaseObject):
|
|||
return self.obj.Position
|
||||
@property
|
||||
def x(self):
|
||||
"""Position X"""
|
||||
return self.position.X
|
||||
@x.setter
|
||||
def x(self, value):
|
||||
|
@ -144,6 +156,7 @@ class LOShape(BaseObject):
|
|||
|
||||
@property
|
||||
def y(self):
|
||||
"""Position Y"""
|
||||
return self.position.Y
|
||||
@y.setter
|
||||
def y(self, value):
|
||||
|
@ -199,11 +212,69 @@ class LOShape(BaseObject):
|
|||
self.obj.LayerID = value
|
||||
|
||||
@property
|
||||
def is_range(self):
|
||||
return False
|
||||
def type(self):
|
||||
mt = self.obj.GraphicURL.MimeType
|
||||
mime_type = self.MIME_TYPE.get(mt, mt)
|
||||
return mime_type
|
||||
|
||||
# ~ not work
|
||||
@property
|
||||
def visible(self):
|
||||
return self.obj.Visible
|
||||
@visible.setter
|
||||
def visible(self, value):
|
||||
self.obj.Visible = value
|
||||
|
||||
@property
|
||||
def is_cell(self):
|
||||
return False
|
||||
def doc(self):
|
||||
return self.obj.Parent.Forms.Parent
|
||||
|
||||
def remove(self):
|
||||
"""Auto remove"""
|
||||
self.obj.Parent.remove(self.obj)
|
||||
return
|
||||
|
||||
def save(self, path: str='', name: str=''):
|
||||
"""Save image"""
|
||||
if not path:
|
||||
path = Paths(self.doc.URL).path
|
||||
if not name:
|
||||
name = self.name.replace(' ', '_')
|
||||
|
||||
path_img = Paths.join(path, f'{name}.{self.type}')
|
||||
data = IOStream.to_bin(self.obj.GraphicStream)
|
||||
Paths.save_bin(path_img, data)
|
||||
|
||||
return path_img
|
||||
|
||||
def _get_graphic(self):
|
||||
stream = self.obj.GraphicStream
|
||||
buffer = IOStream.output()
|
||||
_, data = stream.readBytes(buffer, stream.available())
|
||||
stream = get_input_stream(data)
|
||||
gp = create_instance('com.sun.star.graphic.GraphicProvider')
|
||||
properties = dict_to_property({'InputStream': stream})
|
||||
graphic = gp.queryGraphic(properties)
|
||||
return graphic
|
||||
|
||||
def clone(self, draw_page=None):
|
||||
"""Clone image"""
|
||||
image = self.doc.createInstance('com.sun.star.drawing.GraphicObjectShape')
|
||||
image.Graphic = self._get_graphic()
|
||||
plus = 0
|
||||
if draw_page is None:
|
||||
draw_page = self.obj.Parent
|
||||
plus = 1000
|
||||
else:
|
||||
if hasattr(draw_page, 'obj'):
|
||||
draw_page = draw_page.obj
|
||||
|
||||
draw_page.add(image)
|
||||
image.Size = self.size
|
||||
position = self.position
|
||||
position.X += plus
|
||||
position.Y += plus
|
||||
image.Position = position
|
||||
return LOShape(image)
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import unohelper
|
||||
from com.sun.star.io import IOException, XOutputStream
|
||||
from .easymain import create_instance
|
||||
|
||||
|
||||
# UNO Enum
|
||||
class MessageBoxType():
|
||||
|
@ -9,3 +13,54 @@ class MessageBoxType():
|
|||
"""
|
||||
from com.sun.star.awt.MessageBoxType \
|
||||
import MESSAGEBOX, INFOBOX, WARNINGBOX, ERRORBOX, QUERYBOX
|
||||
|
||||
|
||||
class IOStream(object):
|
||||
"""Classe for input/output stream"""
|
||||
|
||||
class OutputStream(unohelper.Base, XOutputStream):
|
||||
|
||||
def __init__(self):
|
||||
self._buffer = b''
|
||||
self.closed = 0
|
||||
|
||||
@property
|
||||
def buffer(self):
|
||||
return self._buffer
|
||||
|
||||
def closeOutput(self):
|
||||
self.closed = 1
|
||||
|
||||
def writeBytes(self, seq):
|
||||
if seq.value:
|
||||
self._buffer = seq.value
|
||||
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def buffer(cls):
|
||||
return io.BytesIO()
|
||||
|
||||
@classmethod
|
||||
def input(cls, buffer):
|
||||
service = 'com.sun.star.io.SequenceInputStream'
|
||||
stream = create_instance(service, True)
|
||||
stream.initialize((uno.ByteSequence(buffer.getvalue()),))
|
||||
return stream
|
||||
|
||||
@classmethod
|
||||
def output(cls):
|
||||
return cls.OutputStream()
|
||||
|
||||
@classmethod
|
||||
def to_bin(cls, stream):
|
||||
buffer = cls.OutputStream()
|
||||
_, data = stream.readBytes(buffer, stream.available())
|
||||
return data.value
|
||||
|
||||
|
||||
def get_input_stream(data):
|
||||
stream = create_instance('com.sun.star.io.SequenceInputStream', True)
|
||||
stream.initialize((data,))
|
||||
return stream
|
||||
|
|
Loading…
Reference in New Issue