He creado un modulo (que la neta no sé si sea una clase, un componente, una simple función, un objeto..... de POP no sé nada, jo!) que crea un documento ODS (una hoja de cálculo de Open Document) a partir de los datos de una TableView o un GridView. Dicho modulo es muy sencillo y sólo se limita a pasar la info, no conserva los formatos de fuente.
Para el que le interese, aquí les dejo mi código:
' gambas module file
PRIVATE pathOpendoc AS String = "/tmp/opendocgambas/"
PUBLIC FUNCTION saveODS(controlx AS Object, pathODS AS String)
DIM writer AS XmlWriter
DIM filex AS File
DIM iCount AS Integer
DIM jCount AS Integer
IF Object.Type(controlx) = "GridView" OR IF Object.Type(controlx) = "TableView" THEN
TRY MKDIR pathOpendoc
TRY MKDIR pathOpendoc &/ "Configurations2"
TRY MKDIR pathOpendoc &/ "META-INF"
TRY MKDIR pathOpendoc &/ "Thumbnails"
filex = OPEN pathOpendoc &/ "mimetype" FOR INPUT CREATE
PRINT #filex, "application/vnd.oasis.opendocument.spreadsheet"; ' El ";" es para no insertar una terminación de línea
CLOSE #filex
writer = NEW XmlWriter
WITH writer
.Open(pathOpendoc &/ "META-INF/manifest.xml", TRUE, "UTF-8")
.StartElement("manifest:manifest", ["xmlns:manifest", "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"])
.StartElement("manifest:file-entry", ["manifest:media-type", "application/vnd.oasis.opendocument.spreadsheet", "manifest:version", "1.2", "manifest:full-path", "/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Configurations2/statusbar/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Configurations2/accelerator/current.xml"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Configurations2/accelerator/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Configurations2/floater/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Configurations2/popupmenu/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Configurations2/progressbar/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Configurations2/menubar/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Configurations2/toolbar/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Configurations2/images/Bitmaps/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Configurations2/images/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", "application/vnd.sun.xml.ui.configuration", "manifest:full-path", "Configurations2/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", "text/xml", "manifest:full-path", "content.xml"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", "text/xml", "manifest:full-path", "styles.xml"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", "text/xml", "manifest:full-path", "meta.xml"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Thumbnails/thumbnail.png"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Thumbnails/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", "text/xml", "manifest:full-path", "settings.xml"])
.EndElement()
.EndElement
.EndDocument
END WITH
writer = NEW XmlWriter
writer.Open(pathOpendoc &/ "content.xml", TRUE, "UTF-8")
writer.StartElement("office:document-content")
writer.Attribute("xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0")
writer.Attribute("xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0")
writer.Attribute("xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0")
writer.Attribute("xmlns:table", "urn:oasis:names:tc:opendocument:xmlns:table:1.0")
writer.Attribute("xmlns:number", "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0")
writer.Attribute("xmlns:chart", "urn:oasis:names:tc:opendocument:xmlns:chart:1.0")
writer.Attribute("xmlns:form", "urn:oasis:names:tc:opendocument:xmlns:form:1.0")
writer.Attribute("xmlns:oooc", "http://openoffice.org/2004/calc")
writer.Attribute("xmlns:field", "urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0")
writer.Attribute("xmlns:formx", "urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0")
writer.Attribute("office:version", "1.2")
writer.StartElement("office:body")
writer.StartElement("office:spreadsheet")
writer.StartElement("table:table", ["table:name", CStr(controlx.Name), "table:print", "false"])
IF controlx.Header = GridView.Horizontal OR IF controlx.Header = GridView.Both THEN
writer.StartElement("table:table-row")
FOR jCount = 0 TO controlx.Columns.Count - 1
writer.StartElement("table:table-cell", ["office:value-type", "string"])
writer.Element("text:p", controlx.Columns[jCount].Text)
writer.EndElement()
NEXT
writer.EndElement()
ENDIF
FOR iCount = 0 TO controlx.Rows.Count - 1
writer.StartElement("table:table-row")
FOR jCount = 0 TO controlx.Columns.Count - 1
writer.StartElement("table:table-cell") ', ["office:value-type", "string"])
IF Str$(Val(controlx[iCount, jCount].Text)) = controlx[iCount, jCount].Text THEN
writer.Attribute("office:value-type", "float")
writer.Attribute("office:value", controlx[iCount, jCount].Text)
ELSE
writer.Attribute("office:value-type", "string")
ENDIF
writer.Element("text:p", controlx[iCount, jCount].Text)
writer.EndElement()
NEXT
writer.EndElement()
NEXT
writer.EndElement()
writer.EndElement()
writer.EndElement()
writer.EndDocument()
filex = OPEN pathOpendoc &/ "pckods" FOR INPUT CREATE
PRINT #filex, "#!/bin/bash"
PRINT #filex, "# Script creado con gambas, comprime ficheros para crear un documento ODS"
PRINT #filex, "cd $(dirname $0)"
PRINT #filex, "zip -r $1 Configurations2 META-INF Thumbnails content.xml mimetype"
CLOSE #filex
EXEC ["chmod", "+x", pathOpendoc &/ "pckods"] WAIT
EXEC [pathOpendoc &/ "pckods", pathODS] WAIT
ELSE
ERROR "El control no es un GridView o TableView"
ENDIF
END
PRIVATE pathOpendoc AS String = "/tmp/opendocgambas/"
PUBLIC FUNCTION saveODS(controlx AS Object, pathODS AS String)
DIM writer AS XmlWriter
DIM filex AS File
DIM iCount AS Integer
DIM jCount AS Integer
IF Object.Type(controlx) = "GridView" OR IF Object.Type(controlx) = "TableView" THEN
TRY MKDIR pathOpendoc
TRY MKDIR pathOpendoc &/ "Configurations2"
TRY MKDIR pathOpendoc &/ "META-INF"
TRY MKDIR pathOpendoc &/ "Thumbnails"
filex = OPEN pathOpendoc &/ "mimetype" FOR INPUT CREATE
PRINT #filex, "application/vnd.oasis.opendocument.spreadsheet"; ' El ";" es para no insertar una terminación de línea
CLOSE #filex
writer = NEW XmlWriter
WITH writer
.Open(pathOpendoc &/ "META-INF/manifest.xml", TRUE, "UTF-8")
.StartElement("manifest:manifest", ["xmlns:manifest", "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"])
.StartElement("manifest:file-entry", ["manifest:media-type", "application/vnd.oasis.opendocument.spreadsheet", "manifest:version", "1.2", "manifest:full-path", "/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Configurations2/statusbar/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Configurations2/accelerator/current.xml"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Configurations2/accelerator/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Configurations2/floater/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Configurations2/popupmenu/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Configurations2/progressbar/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Configurations2/menubar/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Configurations2/toolbar/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Configurations2/images/Bitmaps/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Configurations2/images/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", "application/vnd.sun.xml.ui.configuration", "manifest:full-path", "Configurations2/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", "text/xml", "manifest:full-path", "content.xml"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", "text/xml", "manifest:full-path", "styles.xml"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", "text/xml", "manifest:full-path", "meta.xml"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Thumbnails/thumbnail.png"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", " ", "manifest:full-path", "Thumbnails/"])
.EndElement()
.StartElement("manifest:file-entry", ["manifest:media-type", "text/xml", "manifest:full-path", "settings.xml"])
.EndElement()
.EndElement
.EndDocument
END WITH
writer = NEW XmlWriter
writer.Open(pathOpendoc &/ "content.xml", TRUE, "UTF-8")
writer.StartElement("office:document-content")
writer.Attribute("xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0")
writer.Attribute("xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0")
writer.Attribute("xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0")
writer.Attribute("xmlns:table", "urn:oasis:names:tc:opendocument:xmlns:table:1.0")
writer.Attribute("xmlns:number", "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0")
writer.Attribute("xmlns:chart", "urn:oasis:names:tc:opendocument:xmlns:chart:1.0")
writer.Attribute("xmlns:form", "urn:oasis:names:tc:opendocument:xmlns:form:1.0")
writer.Attribute("xmlns:oooc", "http://openoffice.org/2004/calc")
writer.Attribute("xmlns:field", "urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0")
writer.Attribute("xmlns:formx", "urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0")
writer.Attribute("office:version", "1.2")
writer.StartElement("office:body")
writer.StartElement("office:spreadsheet")
writer.StartElement("table:table", ["table:name", CStr(controlx.Name), "table:print", "false"])
IF controlx.Header = GridView.Horizontal OR IF controlx.Header = GridView.Both THEN
writer.StartElement("table:table-row")
FOR jCount = 0 TO controlx.Columns.Count - 1
writer.StartElement("table:table-cell", ["office:value-type", "string"])
writer.Element("text:p", controlx.Columns[jCount].Text)
writer.EndElement()
NEXT
writer.EndElement()
ENDIF
FOR iCount = 0 TO controlx.Rows.Count - 1
writer.StartElement("table:table-row")
FOR jCount = 0 TO controlx.Columns.Count - 1
writer.StartElement("table:table-cell") ', ["office:value-type", "string"])
IF Str$(Val(controlx[iCount, jCount].Text)) = controlx[iCount, jCount].Text THEN
writer.Attribute("office:value-type", "float")
writer.Attribute("office:value", controlx[iCount, jCount].Text)
ELSE
writer.Attribute("office:value-type", "string")
ENDIF
writer.Element("text:p", controlx[iCount, jCount].Text)
writer.EndElement()
NEXT
writer.EndElement()
NEXT
writer.EndElement()
writer.EndElement()
writer.EndElement()
writer.EndDocument()
filex = OPEN pathOpendoc &/ "pckods" FOR INPUT CREATE
PRINT #filex, "#!/bin/bash"
PRINT #filex, "# Script creado con gambas, comprime ficheros para crear un documento ODS"
PRINT #filex, "cd $(dirname $0)"
PRINT #filex, "zip -r $1 Configurations2 META-INF Thumbnails content.xml mimetype"
CLOSE #filex
EXEC ["chmod", "+x", pathOpendoc &/ "pckods"] WAIT
EXEC [pathOpendoc &/ "pckods", pathODS] WAIT
ELSE
ERROR "El control no es un GridView o TableView"
ENDIF
END
Y un ejemplo sencillo que muestra la utilidad del anterior código:
' gambas class file
PUBLIC SUB Form_Open()
WITH GridView1
'.Header = GridView.Horizontal
.Header = GridView.Both
.Columns.Count = 3
.Rows.Count = 3
END WITH
GridView1.Columns[0].Text = "Colunma0"
GridView1[0, 0].Text = "hola"
GridView1[0, 1].Text = "1 perro"
GridView1[1, 1].Text = "10.5"
GridView1[2, 2].Text = "123"
opendoc.saveODS(GridView1, User.Home &/ "test.ods")
END
PUBLIC SUB Form_Open()
WITH GridView1
'.Header = GridView.Horizontal
.Header = GridView.Both
.Columns.Count = 3
.Rows.Count = 3
END WITH
GridView1.Columns[0].Text = "Colunma0"
GridView1[0, 0].Text = "hola"
GridView1[0, 1].Text = "1 perro"
GridView1[1, 1].Text = "10.5"
GridView1[2, 2].Text = "123"
opendoc.saveODS(GridView1, User.Home &/ "test.ods")
END
CLICK ¡¡¡Descarga las fuentes!!!! CLICK
Hilos relacionados:
Pastear Un Gridview A Una Hoja De Cálculo
Exportacion A Hoja De Calculo Con Formato
Saludos!
EDITO:
Se me olvidó mencionar que es necesario el componente gb.xml y el paquete zip