OpenXLSX es una biblioteca C ++ para leer, escribir, crear y modificar archivos Microsoft Excel®, con el formato .xlsx.
Como dice el encabezado, el último "lanzamiento" que se muestra en https://github.com/troldal/openxlsx/releases es de 2021-11-06, y severamente desactualizado, tire/descargue la última versión SW directamente desde el repositorio en su estado actual. Enlace para aquellos que no quieren usar git : https://github.com/troldal/openxlsx/archive/refs/heads/master.zip
Revisé el código XLDATETime en respuesta al #299 y solucionó un error que creo que podría haberme introducido. Disculpas, las fechas ahora deben construirse correctamente a partir de double , struct tm y time_t y convertir de nuevo a struct tm .
El historial de cambio se encuentra en el registro de cambio detallado.
Hoy, las características de la rama de desarrollo finalmente llegaron a la rama principal :) Para más detalles, consulte el registro de cambio detallado a continuación.
En resumen:
OpenXLSX/headers/XLStyles.hpp : la clase XLSTYLES (y muchas subclases), proporcionando acceso casi completo a todas las capacidades de formato de Excel.OpenXLSX/headers/XLMergeCells.hpp y XLSheet.hpp : la clase XLMerGeCells se hace accesible a través de la hoja de trabajo XL para crear/eliminar las fusiones de celdaExamples/Demo10.cpp demuestra cómo se usan los estilos y las fusiones Nota: La sección que está deshabilitada con testBasics = false romperá la hoja de cálculo de Excel resultante si está habilitado, el único propósito es demostrar acceso a todas las clases y métodos nuevos. Si desea usarlos, asegúrese de usarlos correctamenteNota en XlNumberFormat (s) : Al contrario de todos los demás elementos XLSTYLES, estos no usan un índice dentro del XML como la ID de referencia (xlCellFormat :: setNumberFormatID), pero en su lugar se puede establecer una identificación definida por el usuario que se puede configurar a través de XLNumberFormat :: setNumberFormAd, y para un XLCellFormat, se puede establecer en un format de forma de autodefensores, o a un format de format, o a un format o a un format o a un format o a un format de forma a un format de forma predefinido por MS. En general, para formatos personalizados, se recomienda usar IDS> 100.
En la lista de tareas pendientes:
Hace un par de días finalmente tuve el tiempo de aprender suficiente funcionalidad GIT para poder trabajar con sucursales. Así que creé una rama de desarrollo con las características más recientes que he mencionado en algunas solicitudes / problemas de extracción. Siéntete libre de echar un vistazo. De esta manera, no tiene que esperar hasta que se actualice el repositorio principal.
Cerró una multitud de solicitudes de extracción que se habían implementado en la actualización de mayo de 2024, implementó dos editoriales más de PR #246 y #253.
Después de un largo período de inactividad, he decidido reanudar el desarrollo de OpenXLSX. El código se ha limpiado y se ha solucionado un número significativo de errores. La biblioteca ha sido probada en Windows, MacOS y Linux, y debe funcionar en todas las plataformas.
Me gustaría extender mi sincero agradecimiento a todas las personas que han contribuido al proyecto, ya sea informando errores, sugiriendo características o enviando solicitudes de extracción. También me gustaría agradecer a todas las personas que han protagonizado el proyecto y que han mostrado interés en el proyecto.
En particular, me gustaría agradecer a Lars Uffmann (https://codeberg.org/lars_uffmann/) por sus contribuciones al proyecto. Lars ha gastado un tiempo y un esfuerzo significativos en la limpieza del código, solucionando errores e implementando nuevas funciones. Sin su ayuda, el proyecto no habría estado en el estado que está hoy.
Muchos lenguajes de programación tienen la capacidad de modificar los archivos de Excel, ya sea de forma nativa o en forma de bibliotecas de código abierto. Esto incluye Python, Java y C#. Para C ++, sin embargo, las cosas están más dispersas. Si bien hay algunas bibliotecas, generalmente son menos maduras y tienen un conjunto de características más pequeño que para otros idiomas.
Debido a que no hay una biblioteca de código abierto que se ajuste completamente a mis necesidades, decidí desarrollar la biblioteca OpenXLSX.
La ambición es que OpenXLSX debería poder leer, escribir, crear y modificar archivos de Excel (datos y formatear), y hacerlo con la menor cantidad de dependencias posible. Actualmente, OpenXLSX depende de las siguientes bibliotecas de terceros:
Estas bibliotecas son todas solo de encabezado e incluidas en el repositorio, es decir, no es necesario descargar y construir por separado.
Además, el enfoque se ha puesto a la velocidad , no al uso de la memoria (aunque hay opciones para reducir el uso de la memoria, a costa de velocidad; más sobre eso más adelante).
OpenXLSX ha sido probado en las siguientes plataformas/compiladores. Tenga en cuenta que A '-' no significa que OpenXLSX no funcione; Simplemente significa que no ha sido probado:
| GCC | Sonido metálico | MSVC | |
|---|---|---|---|
| Windows | Mingw | Mingw | + + |
| Cygwin | - | - | N / A |
| Macosa | + + | + + | N / A |
| Linux | + + | + + | N / A |
Las siguientes versiones del compilador deberían poder compilar OpenXLSX sin errores:
Clang 7 debería poder compilar OpenXLSX, pero aparentemente hay un error en la implementación de la variante STD ::, que causa errores del compilador.
Visual Studio 2017 también debería funcionar, pero no se ha probado.
OpenXLSX utiliza Cmake como sistema de compilación (o generador de sistema de compilación, para ser exacto). Por lo tanto, debe instalar CMake primero, para construir OpenXLSX. Puede encontrar instrucciones de instalación en www.cmake.org.
La biblioteca OpenXLSX se encuentra en el subdirectorio OpenXLSX a este repositorio. El subdirectorio OpenXLSX es un proyecto CMake autónomo; Si usa CMake para su propio proyecto, puede agregar la carpeta OpenXLSX como subdirectorio a su propio proyecto. Alternativamente, puede usar CMake para generar archivos de fabricación o archivos de proyecto para una cadena de herramientas de su elección. Ambos métodos se describen a continuación.
Con mucho, la forma más fácil de usar OpenXLSX en su propio proyecto es usar CMake usted mismo y luego agregar la carpeta OpenXLSX como subdirectorio al árbol de origen de su propio proyecto. Varios proyectos de CMAKE de compatibilidad con IDE, especialmente Visual Studio 2019, JetBrains Clion y QT Creator. Si usa Visual Studio, debe seleccionar específicamente el 'Proyecto CMake' al crear un nuevo proyecto.
El principal beneficio de incluir la biblioteca OpenXLSX como subcarpeta fuente es que no es necesario localizar específicamente la biblioteca y los archivos de encabezado; Cmake se encargará de eso por ti. Además, la biblioteca se construirá utilizando la misma configuración (depuración, versión, etc.) que su proyecto. En particular, este es un beneficio en Windows, donde no es posible usar bibliotecas de lanzamiento en un proyecto de depuración (y viceversa) cuando los objetos STL se pasan a través de la interfaz de la biblioteca, ya que están en OpenXLSX. Al incluir la fuente OpenXLSX, esto no será un problema.
Al usar el comando add_subdirectory() en el archivo cmakelists.txt para su proyecto, puede obtener acceso a los encabezados y archivos de biblioteca de OpenXLSX. OpenXLSX puede generar una biblioteca compartida o una biblioteca estática. Por defecto, producirá una biblioteca compartida, pero puede cambiarla en el archivo OpenXLSX cmakelists.txt. La biblioteca se encuentra en un espacio de nombres llamado OpenXLSX; Por lo tanto, el nombre completo de la biblioteca es OpenXLSX::OpenXLSX .
El siguiente fragmento es un archivo mínimo cmakelists.txt para su propio proyecto, que incluye OpenXLSX como subdirectorio. Tenga en cuenta que la ubicación de salida de los binarios se establece en un directorio común. En Linux y MacOS, esto no es realmente necesario, pero en Windows, esto facilitará su vida, ya que de otro modo tendría que copiar el archivo de biblioteca compartida OpenXLSX en la ubicación de su ejecutable para ejecutarse.
cmake_minimum_required ( VERSION 3.15)
project (MyProject)
set (CMAKE_CXX_STANDARD 17)
# Set the build output location to a common directory
set ( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} / output )
set ( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} / output )
set ( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} / output )
add_subdirectory (OpenXLSX)
add_executable (MyProject main.cpp)
target_link_libraries (MyProject OpenXLSX::OpenXLSX)Usando lo anterior, debe poder compilar y ejecutar el siguiente código, que generará un nuevo archivo de Excel llamado 'Spreadsheet.xlsx':
# include < OpenXLSX.hpp >
using namespace OpenXLSX ;
int main () {
XLDocument doc;
doc. create ( " Spreadsheet.xlsx " );
auto wks = doc. workbook (). worksheet ( " Sheet1 " );
wks. cell ( " A1 " ). value () = " Hello, OpenXLSX! " ;
doc. save ();
return 0 ;
}Si desea producir los binarios OpenXLSX e incluirlos en su proyecto usted mismo, se puede hacer usando CMake y una cadena de herramientas de compilador de su elección.
Desde la línea de comando, navegue el subdirectorio OpenXLSX de la raíz del proyecto y ejecute los siguientes comandos:
mkdir build
cd build
cmake ..
El último comando configurará el proyecto. Esto configurará el proyecto utilizando la cadena de herramientas predeterminada. Si desea especificar la cadena de herramientas, escriba cmake -G "<toolchain>" .. con <toolchain> siendo la cadena de herramientas que desea usar, por ejemplo "Unix Makefiles", "Ninja", "Xcode" o "Visual Studio 16 2019". Vea la documentación de CMake para más detalles.
Finalmente, puede construir la biblioteca usando el comando:
cmake --build . --target OpenXLSX --config Release
Puede cambiar los argumentos --target y --config a lo que desee usar.
Cuando se construye, puede instalarlo utilizando el siguiente comando:
cmake --install .
Este comando instalará la biblioteca y los archivos de encabezado en la ubicación predeterminada en su plataforma (generalmente/usr/local/en Linux y macOS, y c: archivos de programa en Windows). Puede establecer una ubicación diferente usando el argumento - -prefix.
Tenga en cuenta que, dependiendo de la plataforma, puede no ser posible instalar bibliotecas de depuración y liberación. En Linux y MacOS, este no es un gran problema, ya que las bibliotecas de lanzamiento se pueden usar tanto para ejecutables de depuración como de liberación. No es así para Windows, donde la configuración de la biblioteca debe ser la misma que para el ejecutable que lo vincula. Por esa razón, en Windows, es mucho más fácil incluir la carpeta de origen OpenXLSX como subdirectorio para su proyecto CMake; Te ahorrará muchos dolores de cabeza.
OpenXLSX sigue funcionando en progreso. La siguiente es una lista de características que se han implementado y deberían funcionar correctamente:
Las características relacionadas con el formato, los gráficos y las cifras no se han implementado, y no se planea que se encuentren en el futuro cercano.
Cabe señalar que la creación de objetos const xDocument, actualmente no funciona.
La siguiente tabla es la salida de un punto de referencia (usando la biblioteca de referencia de Google), que muestra que el acceso de lectura/escritura se puede realizar a una velocidad de alrededor de 4,000,000 de celdas por segundo. Los números de puntos flotantes son algo más bajos, debido a la conversión a/desde cadenas en el archivo .xml.
Run on (16 X 2300 MHz CPU s)
CPU Caches:
L1 Data 32 KiB (x8)
L1 Instruction 32 KiB (x8)
L2 Unified 256 KiB (x8)
L3 Unified 16384 KiB (x1)
Load Average: 2.46, 2.25, 2.19
---------------------------------------------------------------------------
Benchmark Time CPU Iterations UserCounters...
---------------------------------------------------------------------------
BM_WriteStrings 2484 ms 2482 ms 1 items=8.38861M items_per_second=3.37956M/s
BM_WriteIntegers 1949 ms 1949 ms 1 items=8.38861M items_per_second=4.30485M/s
BM_WriteFloats 4720 ms 4719 ms 1 items=8.38861M items_per_second=1.77767M/s
BM_WriteBools 2167 ms 2166 ms 1 items=8.38861M items_per_second=3.87247M/s
BM_ReadStrings 1883 ms 1882 ms 1 items=8.38861M items_per_second=4.45776M/s
BM_ReadIntegers 1641 ms 1641 ms 1 items=8.38861M items_per_second=5.11252M/s
BM_ReadFloats 4173 ms 4172 ms 1 items=8.38861M items_per_second=2.01078M/s
BM_ReadBools 1898 ms 1898 ms 1 items=8.38861M items_per_second=4.4205M/s
Un archivo .xlsx es esencialmente un montón de archivos .xml en un archivo .zip. Internamente, OpenXLSX usa la biblioteca de Miniz para comprimir/descomprimir el archivo .zip, y resulta que Miniz tiene un límite superior con respecto a los tamaños de archivo que puede manejar.
El tamaño máximo de archivo permitido para un archivo en un archivo (es decir, la entrada en un archivo .zip, no en el archivo en sí) es de 4 GB (sin comprimir). Por lo general, el archivo más grande en un archivo/archivo .xlsx será los archivos .xml que contienen los datos de la hoja de trabajo. Es decir, los datos de la hoja de trabajo no pueden exceder los 4 GB. A lo que eso se traduce en términos de filas y columnas depende mucho del tipo de datos, pero 1,048,576 filas x 128 columnas llenas de enteros de 4 dígitos tomarán aprox. 4 GB. El tamaño del archivo comprimido también depende de los datos contenidos en la hoja de trabajo, así como del algoritmo de compresión utilizado, pero un libro de trabajo con una sola hoja de trabajo de 4 GB generalmente tendrá un tamaño comprimido de 300-350 MB.
La limitación de 4 GB solo está relacionada con una sola entrada en un archivo, no con el tamaño total del archivo. Eso significa que si un archivo contiene múltiples entradas con un tamaño de 4 GB, Miniz aún puede manejarlo. Para OpenXLSX, esto significa que todavía se puede abrir un libro de trabajo con varias hojas de trabajo grandes.
OpenXLSX utiliza la biblioteca Pugixml para analizar y manipular archivos .xml en el archivo .xlsx. Pugixml es un analizador DOM, que lee todo el documento .xml en la memoria. Eso hace que el análisis y la manipulación sea increíblemente rápido.
Sin embargo, todas las opciones tienen consecuencias, y el uso de un analizador DOM también puede exigir mucha memoria. Para hojas de cálculo pequeñas, no debería ser un problema, pero si necesita manipular hojas de cálculo grandes, es posible que necesite mucha memoria.
La siguiente tabla da una indicación de cuántas columnas de datos pueden ser manejadas por OpenXLSX (suponiendo 1,048,576 filas):
| Columnas | |
|---|---|
| 8 GB RAM | 8-16 |
| 16 GB RAM | 32-64 |
| 32 GB RAM | 128-256 |
Su kilage puede variar. El rendimiento de OpenXLSX dependerá del tipo de datos en la hoja de cálculo.
Tenga en cuenta también que se recomienda usar OpenXLSX en modo de 64 bits. Si bien se puede usar fácilmente en modo de 32 bits, solo puede acceder a 4 GB de RAM, lo que limitará severamente la utilidad al manejar hojas de cálculo grandes.
Si el consumo de memoria es un problema para usted, puede construir la biblioteca OpenXLSX en modo Compacto (busque el archivo Compact_Compact_Mode en el archivo cmakelists.txt), que habilitará el modo compacto de Pugixml. OpenXLSX usará menos memoria, pero también se ejecutará más lento. Vea más detalles en la documentación de Pugixml aquí. Un caso de prueba ejecutado en Linux VM con 8 GB de RAM reveló que OpenXLSX podría manejar una hoja de trabajo con 1,048,576 filas x 32 columnas en modo compacto, versus 1,048,576 filas x 16 columnas en modo predeterminado.
Con mucho, la mayoría de las preguntas que obtengo sobre OpenXLSX en GitHub, está relacionada con Unicode. Aparentemente es (y comprensiblemente) una fuente de gran confusión para muchas personas.
Al principio, decidí que OpenXLSX debería centrarse en la parte de Excel, y no ser una utilidad de codificación/conversión de texto también. Por lo tanto, toda la entrada/salida de texto a OpenXLSX debe estar en la codificación UTF-8 ... de lo contrario, no funcionará como se esperaba. También puede ser necesario que los archivos del código fuente se guarden en formato UTF-8. Si, por ejemplo, un archivo de origen se guarda en formato UTF-16, entonces cualquier literario de cadena también estará en UTF-16. Entonces, si tiene literales de cadena codificados en su código fuente, entonces el archivo fuente también debe guardar en formato UTF-8.
Todas las manipulaciones y el uso de la cadena en OpenXLSX usan la cadena C ++ std ::, que está codificando agnóstico, pero se puede usar fácilmente para la codificación UTF-8. Además, Excel usa la codificación UTF-8 internamente (en realidad, es posible usar otras codificaciones, pero no estoy seguro de eso).
Por la razón anterior, si trabaja con otras codificaciones de texto, debe convertirse a/desde UTF-8 usted mismo . Hay una serie de opciones (por ejemplo, Boost.Nowide o Boost.text). Internamente, OpenXLSX usa BOOST.NOWIDE; Tiene una serie de funciones útiles para abrir archivos y convertir entre std :: string y std :: wstring, etc. También le sugeriré que vea la presentación de James McNellis en CPPCON 2014, y lea el blog de Joel Spolsky.
Unicode en Windows es particularmente desafiante. Si bien UTF-8 es bien compatible con Linux y MacOS, el soporte en Windows es más limitado. Por ejemplo, la producción de caracteres no ASCII (por ejemplo, caracteres chinos o japoneses) a la ventana terminal se verá como galimatías. Como se mencionó, a veces también debe tener en cuenta la codificación de texto de los archivos de origen. Algunos usuarios han tenido problemas con OpenXLSX bloqueando al abrir/crear archivos .xlsx con nombres de archivo que no son ASCII, donde resultó que el código fuente para el programa de prueba estaba en una codificación no UTF-8, y por lo tanto, la cadena de entrada a OpenXLSX también no era UTF-8. Para mantenerse cuerdo, recomiendo que los archivos de código fuente siempre estén en archivos UTF-8; Todos los IDE que conozco pueden manejar los archivos de código fuente en la codificación UTF-8. ¿Bienvenido al maravilloso mundo de Unicode en Windows?
Un archivo de Excel es esencialmente solo un montón de archivos .xml envueltos en un archivo .zip. OpenXLSX utiliza una biblioteca de terceros para extraer los archivos .xml del archivo .zip. La biblioteca predeterminada utilizada por OpenXLSX es Zippy, que es un envoltorio orientado a objetos alrededor de Miniz. La biblioteca de Miniz es rápida y solo es de encabezado, que es ideal para OpenXLSX.
Sin embargo, es posible usar una biblioteca postal diferente, si lo desea. En casos raros, puede experimentar problemas de estabilidad con Miniz. En esos casos, puede ser útil probar una biblioteca postal diferente.
El uso de la biblioteca Zippy/Miniz no requiere esfuerzos especiales; Funcionará directamente de la caja. Sin embargo, usar una biblioteca postal diferente requerirá algo de trabajo.
Para usar una biblioteca postal diferente, debe crear una clase de envoltorio que se ajuste a la interfaz especificada por la clase Iziparchive. Tenga en cuenta que esto se implementa utilizando el tipo de borrado , lo que significa que no se requiere herencia; La clase solo necesita tener una interfaz conforme, eso es todo. Después de eso, proporcione un objeto de la clase y suministre al constructor OpenXLSX.
Para ver un ejemplo de cómo se hace esto, eche un vistazo a Demo1a en la carpeta de ejemplos. Este ejemplo utiliza una clase llamada CustomZip (usando libzip como la biblioteca ZIP) que se puede encontrar en ejemplos/externo/customzip. Para construir el programa de ejemplo, asegúrese de que Libzip (y sus dependencias) se instale en su computadora y habiliten la opción OpenXLSX_ENABLE_LIBZIP en el archivo cmakelists.txt en la raíz OpenXLSX.
Como se mencionó, el programa Demo1a Ejemplo usa libzip. Libzip es una biblioteca muy estable y ampliamente utilizada. Sin embargo, mi experiencia es que es bastante lento para grandes archivos zip, como hojas de cálculo grandes. Por esa razón, Libzip puede no ser la solución ideal, pero es útil para mostrar cómo se puede usar una biblioteca postal diferente.
En la carpeta 'Ejemplos', encontrará varios programas de ejemplo, que ilustran cómo usar OpenXLSX. Estudiar esos programas de ejemplo es la mejor manera de aprender a usar OpenXLSX. Los programas de ejemplo se anotan, por lo que debería ser relativamente fácil entender lo que está sucediendo.
OpenXLSX ahora puede usar otras bibliotecas zip que la biblioteca Zippy/Miniz predeterminada. Ver Demo1a como un ejemplo de cómo se hace
Esta versión incluye rangos de filas e iteradores. También admite la asignación de contenedores de valores de celda a objetos XLROW. Esto es significativamente más rápido (hasta X2) que usar rangos de células o acceder a las células por referencias celulares.
La arquitectura interna de OpenXLSX se ha rediseñado significativamente desde la versión anterior. La razón es que la biblioteca se estaba convirtiendo en una gran bola de barro, y era cada vez más difícil agregar características y arreglar errores. Con la nueva arquitectura, será (con suerte) más fácil de administrar y agregar nuevas características.
Debido al rediseño de la arquitectura, hay algunos cambios en la interfaz pública. Sin embargo, estos cambios no son significativos, y debería ser fácil de actualizar:
Me doy cuenta de que estos cambios pueden causar problemas a algunos usuarios. Debido a eso, la versión anterior de OpenXLSX se puede encontrar en la rama "Legacy" de este repositorio. Sin embargo, le recomiendo que haga la transición a la nueva versión.
Parece que MS Office no tolera ningún nodo XML de formato antes del nodo <mergeCells> XML; para deshacerse de un mensaje de error en concurso, el último confirmación modifica la función XLSheet::merges para insertar un recién creado <mergeCells> Node directamente después del nódulo <sheetData> .
Estos valores predeterminados faltantes podrían conducir a errores de seguimiento cuando se suponía que cualquier índice de estilo de esta celda es válido para acceder a dicho estilo por índice (excepción si el índice no estaba en un rango válido). Todos los índices de estilo disponibles en un formato de celda ahora están inicializados por cero (sin suposiciones de lo que el estilo con el índice 0 puede configurarse como, normalmente es predeterminado, si desea estar seguro, proporcione una celda con un formato conocido como plantilla de copia a xlcellformats :: create).
XLDocument.hpp : showWarnings() (Configuración predeterminada) y suppressWarnings()XLStyles.hpp : el parámetro suppressWarnings agregado al constructor (predeterminado: false )XLDocument::open : si se llamó suppressWarnings() , suprima las advertencias sobre los archivos XML de comentarios ignorados y los elementos de libro de trabajo no controladoXLDocument::open : m_suppressWarnings La configuración se reenvía al constructor xlstylesXLException.hpp : Se agregó #include <string>XLDocument::open creará una relación de libro de trabajo faltante en _rels/.rels si, y solo si, un libro de trabajo con la ruta predeterminada xl/workbook.xml existe en el archivoXLDocument::create y XLDocument::saveAs , pero las marcó como [[deprecated]] Las nuevas interfaces requieren una especificación explícita de XLForceOverwrite o XLDoNotOverwrite . Una vez que se pueden eliminar las definiciones de la función desaprobada, XLDoNotOverwrite podría convertirse en el nuevo comportamiento predeterminadoOpenXLSX/external/nowide/nowideDemo0 / Mantenlo en el archivo de making como un vehículo de pruebaNotes actualizadasScripts creado con xml-format.sh (pelusa XML, útil para analizar el contenido de ZIP XLSX en un editor de texto)make-gnu.sh a Scripts/make-gnu.shScripts/cmake-cleanup.sh agregados para preparar (¡no ejecutar!) Comandos que eliminan todos los archivos temporales generados por CMakeScripts/demos-cleanup.sh agregados para eliminar todos los archivos XLSX creados por las demostracionesvoid setSavingDeclaration(XLXmlSavingDeclaration const& savingDeclaration) utilizando class XLXmlSavingDeclaration (definida en XLXmlData.hpp ) que puede usarse para pasar una versión XML personalizada, codificación y propiedad independiente a PugixmlNotes/todo-list.txt XLWorksheet ahora permite acceder a un objeto que administra los rangos de celdas fusionadas de la hoja de trabajo
XLMergeCells XLWorksheet::merges() - Acceda a la clase XLMERGECLELS para la hoja de trabajo directamentevoid mergeCells(XLCellRange const& rangeToMerge, bool emptyHiddenCells = false) - células de fusión definidas por rangetomergevoid mergeCells(const std::string& rangeReference, bool emptyHiddenCells = false) - Celillas de fusión definidas por Rangeferencevoid unmergeCells(XLCellRange const& rangeToUnmerge) - Células de desaprobación definidas por Rangetoungevoid unmergeCells(const std::string& rangeReference) - células no menores definidas por rangeference XLMergeCells : Métodos agregados
int32_t XLMergeCells::findMerge(const std::string& reference) - Encuentre una referencia de combinación de combinaciónbool mergeExists(const std::string& reference) - Pruebe si existe una fusión con referenciaint32_t XLMergeCells::findMergeByCell(const std::string& cellRef) - Encuentre una fusión que contenga std :: string cellrefint32_t XLMergeCells::findMergeByCell(XLCellReference cellRef) - Encuentre una fusión que contenga XlCellReference CellRefsize_t count() - Obtenga el recuento de fusiones definidas en la hoja de trabajoconst char* merge(int32_t index) - Obtener una cadena de referencia de fusión en el índiceconst char* operator[](int32_t index) - sobrecarga del operador [] como un atajo para :: fusionarint32_t appendMerge(const std::string& reference) - Defina una nueva fusión, invocada por xlworksheet :: MergeCellsvoid deleteMerge(int32_t index) : elimine la fusión con el índice dado de la hoja de trabajo (= celdas nomergentes), invocado por xlworksheet :: unmergecells Uso de ejemplo agregado de esta funcionalidad a Demo10.cpp
XLDocument::open ahora ignorará las subcarpetas desconocidas (permanecen sin modificar e inaccesibles en la cremallera en la memoria y permanecerán en el archivo al guardar). Esto evita lanzar una excepción para cualquier archivo XLSX escrito por una aplicación "creativa" que agregara elementos desconocidos a esta bibliotecaconstexpr de const unsigned int pugi_parse_settings y lo movió a XLDocument.hpp para que el constante estilos y xlsharedstringsXLStyles - La interfaz se puede encontrar en OpenXLSX/headers/XLStyles.hppExamples/Demo10.cpp demuestra el uso de la nueva funcionalidad de fusión xlstyles y celdasXLCellIterator no creado: ahora puede iterar en un rango y probar XLCellIterator::cellExists antes de acceder a él. Esto permite omitir celdas inexistentes sin crearlas.workbook##.xml , espacios de nombres XML e identificadores aleatorios de 64 bits (relación)xl/workbook.xml ) si se hace referencia correctamente en _rels/.relsbool OpenXLSX::enable_xml_namespaces() debe usarse para habilitar el soporte del espacio de nombres antes de abrir un documento usando EG A Names Space x (como así: <x:row r="1"> ) en todas partesinsert_child_before("x:row", curRow ) en el nodo <y:sheetData> se despojará la x: e inserta un elemento de fila llamado <y:row> , usando el espacio de nombres del nodo principalOpenXLSX/headers/XLXmlParser.hpp ) Tomemos como un último argumento opcional un bool force_ns que, si es verdadero, respetará un espacio de nombres que se pasa a la función para la creación/acceso de nodo. Un ayudante const bool OpenXLSX::XLForceNamespace = true está disponible para la legibilidad de códigoXMLNode::insert_child_before("x:row", curRow, XLForceNamespace) en el nodo <y:sheetData> como arriba, insertará un elemento de fila llamado x:rowid="rId##" donde ## es el número de secuencia, y cuando se agrega un nuevo componente al libro de trabajo, se determina una nueva ID de relación tomando el valor más alto existente dentro del libro de trabajo, y agregando +1 a él. Durante la investigación de [#254] se encontró que un libro de trabajo usaba (aparentemente) enteros de 64 bits aleatorios, almacenados en la forma r:id="Rxx" , siendo xx una representación hexadecimal de un entero de 64 bits.OpenXLSX::UseRandomIDs() debe invocarse para cambiar la funcionalidad de ID antes de abrir dicho documentoOpenXLSX::UseSequentialIDs() se puede usar para restaurar la funcionalidad de identificación de relación predeterminada (secuencial) Nota en enable_xml_namespaces : el soporte del espacio de nombres es transparente y puede usarse con documentos que no usan dichos espacios de nombres. Sin embargo, puede tener un pequeño (<5%) impacto de rendimiento en grandes libros de trabajo y, por lo tanto, es opcional de habilitar.
PRECAUCIÓN CON UseRandomIDs : tenga en cuenta que un modo mixto, donde se abre un documento con soporte de identificación aleatoria y otro sin ID de relación secuencial, no es compatible con el momento. Si tiene que trabajar con documentos de diferentes tipos, siempre debe configurar el comportamiento de ID de relación deseado para el próximo documento, trabajar con eso, cerrarlo y cambiar la configuración de ID de relación antes de abrir el siguiente documento.
Haga caso omiso de ejemplos/demo0.cpp y ejemplos/demo9.cpp por ahora (Demo0 es trivial y se usó para probar el soporte de libros de trabajo no estándar, y Demo9 requiere una revisión con mejores comentarios). Demo9 muestra cómo usar el nuevo XLCellAssignable a Copy-Assign Cell Contents (como Excel Copy & Paste).
XLCellIterator ya no crea celdas vacías solo para iterar sobre ellas, y proporciona ::cellExists() para probar si la celda actualmente puntiaguda ya está en la hoja de trabajo XML, antes de acceder a élXLStylesXLWorksheet ahora proporciona soporte XLMergeCells para fusionar / rangos de celdas innecesidadesDemo10.cpp tiene muchos ejemplos sobre cómo usar la nueva funcionalidad XLSTYLEScustomXml etc en el archivo xlsxXLProperties.cpp XLAppProperties to create <TitlesOfParts> and <HeadingPairs> nodes (and subnodes) if missing, added method alignWorksheets , called by XLDocument::open to ensure that all worksheets listed in the workbook xml are also accounted for in docProps/app.xml .XLProperties.cpp prettyInsertXmlNodeBefore , maybe this can eventually become a global function, paired with a TBW function prettyInsertXmlNodeAfter , and could be used by all classes, cleaning up the code for whitespace support substantially.XLProperties.cpp for <HeadingPairs> subnodes: pairCount -> pairValueParent , pairCountValue -> pairValue Code refactored in XLDocument::open to read the shared strings table while consistently ignoring phonetic tags, which were previously only ignored if the very first child of an <si> tag was a phonetic tag. Will now be ignored anywhere before, after or in between text <t> and rich text <r> tags.
Included a "dumb" fallback solution in XLRelationships.cpp GetTypeFromString to support previously unknown relationship domains, eg type="http://purl.oclc.org/ooxml/officeDocument/relationships/worksheet" . Altered behavior will initially test against the hardcoded relationship domains, and if that test fails to identify a relationship type string, the type string will be searched for an occurrence of /relationships/ and if that substring is found, the type detection fallback will try to evaluate the relationship type based on the substring starting with /relationships/ , ignoring the domain. For the above example, that would result in a test of typeString.substr( comparePos ) == "/relationships/worksheet" , where comparePos == 41 (the position at which substring /relationships/ begins).
In anticipation of a potential future need for a similar "dumb" fallback solution, repeating hardcoded strings in XLContentTypes.cpp GetTypeFromString were also replaced with string constants.
Updated .gitignore to a more generic version that excludes everything and explicitly re-includes all desired files.
BinaryAsHexString : replaced char array with std::string, as ISO C++ standard does not permit variable size arraysRand64 : added explicit type cast, as bitwise shift-left does not do integer promotion to long on the left operand-Wpedantic -Wextra and removed all previously disabled flags after below patchesf( param ) -> f(param) , a[ index ] -> a[index] and if( condition ) -> if (condition) )warning: enumerated and non-enumerated type in conditional expression [-Wextra]void ZipArchive::Save(std::ostream& stream)void ZipArchive::ExtractDir(const std::string& dir, const std::string& dest)void ZipArchive::ExtractAll(const std::string& dest)-Wunused-function by pragma for functions fileExists and isDirectoryuint32_t (was uint64_t ). CAUTION : there is no validity check on the underlying XML (nor was there ever one in case a value was inconsistent with OpenXLSX::MAX_ROWS)-Wsign-comparebool endReached() to eliminate -Wignored-qualifiers (ignored because const on trivial return types accomplishes nothing)OpenXLSX::ignore template, can be used to suppress -Wunused-parameter and -Wunused-variable like so: OpenXLSX::ignore(unusedValue)-Wunused-parameter#pragma warning lines in another pragma to disable -Wunknown-pragmas (on gcc/g++)#pragma GCC diagnostic push#pragma GCC diagnostic ignored "-Wunknown-pragmas" // disable warning about below #pragma warning being unknown# pragma /* offending lines go here */#pragma GCC diagnostic popzippy.hppIZipArchive.hppXLCell.hppXLCellIterator.hppXLCellRange.hppXLCellReference.hppXLCellValue.hppXLColor.hppXLColumn.hppXLCommandQuery.hppXLContentTypes.hppXLDateTime.hppXLDocument.hppXLException.hppXLFormula.hppXLMergeCells.hppXLProperties.hppXLRelationships.hppXLRowData.hppXLRow.hppXLSharedStrings.hppXLSheet.hppXLStyles.hppXLWorkbook.hppXLXmlData.hppXLXmlFile.hppXLZipArchive.hppExamples/Demo5.cpp<Properties> (document) element, was previously wrongly appended to headingPairs/xl/worksheets/sheet* , /xl/sharedStrings.xml , /xl/styles.xml , /xl/theme/theme* ) and otherwise ignored. This fixes an issue when the workbook contains /xl/pivotCache/ and /xl/pivotTables/ entries until support for those is implemented (if ever ;P)<cols> element obtained via a rowNode parent's parentstd::vector< XLStyleIndex > m_columnStyles , and a method fetchColumnStyles that will populate the vector so that it can be passed to the XLCellIterator constructorXLCellIterator::cellExists() without creating the XML for the cell.<font><scheme val="major"/></font> )<font><vertAlign val="subscript"/></font> )<fills><fill><gradientFill>...</gradientFill></fill>...</fills> are now supportedPlease refer to Demo10 and XLStyles.hpp on how to set cell formatting. En breve: