Ver Mensaje Individual
  #5 (permalink)  
Antiguo 01/12/2011, 17:09
Avatar de _cronos2
_cronos2
Colaborador
 
Fecha de Ingreso: junio-2010
Mensajes: 2.062
Antigüedad: 13 años, 11 meses
Puntos: 310
Respuesta: Escribir en .docx

Bien, pues después de investigar he conseguido descubrir varias cosas. La primera es que los .docx son en realidad una especie de "zips" con varias carpetas donde hay archivos XML. Los archivos principales son dos:
1.- "word/document.xml": Estructura del .docx
2.- "word/_rels/document.rels.xml": Guarda las relationships del documento
Entonces los enlaces se ponen en el archivo 1 así:
Código XML:
Ver original
  1. <w:hyperlink r:id="rIdX">
  2. <w:r w:rsidRPr="008D7595">
  3. <w:rPr>
  4. <w:rStyle w:val="Hipervnculo"/>
  5. </w:rPr>
  6. <w:t>Texto</w:t>
  7. </w:r>
  8. </w:hyperlink>
Excepto el <w:t>, el resto de hijos del hyperlink no sé para qué sirven aunque se puede intuir, y en principio no las voy a usar, con poner el texto me sirve.
Después, en el archivo 2, se ponen los Relationships:
Código XML:
Ver original
  1. <Relationship Target="http://www.google.es" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Id="rIdX" TargetMode="External"/>
X es el número del id.
Entonces edité el módulo docx y en la función wordrelationships, que es la que añade todos los Relationships antes de guardar el documento, añadí un parámetro para poder pasarle un array de links y que los añadiera también al archivo 2. Lo puse así:
Código Python:
Ver original
  1. def wordrelationships(relationshiplist, links = []):
  2.     relationships = etree.fromstring(
  3.     '''<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
  4.        </Relationships>'''
  5.     )
  6.    
  7.     count = 1
  8.     for relationship in relationshiplist:
  9.         # Relationship IDs (rId) start at 1.
  10.         relationships.append(
  11.             makeelement('Relationship', attributes = {
  12.                 'Id' : 'rId' + str(count),
  13.                 'Type' : relationship[0],
  14.                 'Target' : relationship[1]
  15.             }, nsprefix = None)
  16.         )
  17.         count += 1
  18.    
  19. # A partir de aquí el código es mío
  20.     namespace = '{http://schemas.openxmlformats.org/officeDocument/2006/relationships}' # nsprefix = 'r'
  21.     if links: # links != []    
  22.         for obj in links:
  23.             relationships.append(
  24.                 makeelement('Relationship', attributes = {
  25.                     'Id' : 'rId' + str(count),
  26.                     'Type' : 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink',
  27.                     'Target' : obj['target'],
  28.                     'TargetMode' : obj['mode']
  29.                 }, attrnsprefix = 'w', tagtext = obj['text'])
  30.             )
  31.            
  32.             obj['hyperlink'].set(namespace + 'id', 'rId' + str(count))
  33.             count += 1
  34.    
  35.     return relationships
Y aquí surgen varios problemas, como era de esperar
A) En vez de hacer un bucle para relationshiplist y otro para links, parece ser que el de links se queda dentro del otro, y por cada Relationship "estándar" que añade, me añade otra vez el Relationship de mi link.
B) Al crear los elementos pongo tanto nsprefix como attrnsprefix 'w', puesto que en una prueba que hice a mano, al inspeccionar los archivos, el prefijo de los tags es "w:", sin embargo en el archivo generado sale "ns0:".
C) Se supone que cuando se guarda el archivo todo el árbol XML se convierte a string para después escribirlo en el nuevo documento, y se hace mediante el etree de lxml:
Código Python:
Ver original
  1. # Serialize our trees into out zip file
  2.     treesandfiles = {document:'word/document.xml',
  3.                      coreprops:'docProps/core.xml',
  4.                      appprops:'docProps/app.xml',
  5.                      contenttypes:'[Content_Types].xml',
  6.                      websettings:'word/webSettings.xml',
  7.                      wordrelationships:'word/_rels/document.xml.rels'}
  8.     for tree in treesandfiles:
  9.         log.info('Saving: '+treesandfiles[tree])
  10.         treestring = etree.tostring(tree, pretty_print=True)
  11.         docxfile.writestr(treesandfiles[tree], treestring)
Al usar el tostring, el parámetro pretty_true es True, así que debería escribirlo con saltos de línea e indentaciones. Sin embargo, cuando me genera el documento, el archivo 2 (el de Relationships) me sale todo en dos líneas:
Código XML:
Ver original
  1. <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
  2.         <Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering" Id="rId1" Target="numbering.xml"/><ns0:Relationship xmlns:ns0="http://schemas.openxmlformats.org/wordprocessingml/2006/main" ns0:TargetMode="External" ns0:Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" ns0:Id="rId2" ns0:Target="http://www.google.es">http://www.google.es</ns0:Relationship><Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Id="rId3" Target="styles.xml"/><ns0:Relationship xmlns:ns0="http://schemas.openxmlformats.org/wordprocessingml/2006/main" ns0:TargetMode="External" ns0:Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" ns0:Id="rId4" ns0:Target="http://www.google.es">http://www.google.es</ns0:Relationship><Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Id="rId5" Target="settings.xml"/><ns0:Relationship xmlns:ns0="http://schemas.openxmlformats.org/wordprocessingml/2006/main" ns0:TargetMode="External" ns0:Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" ns0:Id="rId6" ns0:Target="http://www.google.es">http://www.google.es</ns0:Relationship><Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings" Id="rId7" Target="webSettings.xml"/><ns0:Relationship xmlns:ns0="http://schemas.openxmlformats.org/wordprocessingml/2006/main" ns0:TargetMode="External" ns0:Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" ns0:Id="rId8" ns0:Target="http://www.google.es">http://www.google.es</ns0:Relationship><Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" Id="rId9" Target="fontTable.xml"/><ns0:Relationship xmlns:ns0="http://schemas.openxmlformats.org/wordprocessingml/2006/main" ns0:TargetMode="External" ns0:Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" ns0:Id="rId10" ns0:Target="http://www.google.es">http://www.google.es</ns0:Relationship><Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Id="rId11" Target="theme/theme1.xml"/><ns0:Relationship xmlns:ns0="http://schemas.openxmlformats.org/wordprocessingml/2006/main" ns0:TargetMode="External" ns0:Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" ns0:Id="rId12" ns0:Target="http://www.google.es">http://www.google.es</ns0:Relationship></Relationships>
Ahí también se puede ver lo de que me repite el link que le paso por cada Relationship que añade.
Espero que me podáis ayudar :D
Saludos (:
__________________
" Getting older’s not been on my plans
but it’s never late, it’s never late enough for me to stay. "
Cigarettes - Russian Red