diff options
Diffstat (limited to '')
-rw-r--r-- | doc/overview/doc-orcus.rst | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/doc/overview/doc-orcus.rst b/doc/overview/doc-orcus.rst new file mode 100644 index 0000000..0577d4e --- /dev/null +++ b/doc/overview/doc-orcus.rst @@ -0,0 +1,176 @@ + +.. highlight:: cpp + +Use orcus's spreadsheet document class +====================================== + +If you want to use orcus' :cpp:class:`~orcus::spreadsheet::document` as your +document store, you can use the :cpp:class:`~orcus::spreadsheet::import_factory` +class that orcus provides which already implements all necessary interfaces. +The example code shown below illustrates how to do this: + +.. literalinclude:: ../../doc_example/spreadsheet_doc_1.cpp + :language: C++ + +This example code loads a file saved in the Open Document Spreadsheet format +stored in a directory whose path is to be defined in the environment variable +named ``INPUTDIR``. In this example, we don't check for the validity of ``INPUTDIR`` +for bravity's sake. + +The input file consists of the following content on its first sheet. + +.. figure:: /_static/images/overview/doc-content.png + +While it is not clear from this screenshot, cell C2 contains the formula +**CONCATENATE(A2, " ", B2)** to concatenate the content of A2 and B2 with a +space between them. Cells C3 through C7 also contain similar formula +expressions. + +Let's walk through this code step by step. First, we need to instantiate the +document store. Here we are using the concrete :cpp:class:`~orcus::spreadsheet::document` +class available in orcus. Then immediately pass this document to the +:cpp:class:`~orcus::spreadsheet::import_factory` instance also from orcus: + +.. literalinclude:: ../../doc_example/spreadsheet_doc_1.cpp + :language: C++ + :start-after: //!code-start: instantiate + :end-before: //!code-end: instantiate + :dedent: 4 + +The next step is to create the loader instance and pass the factory to it: + +.. literalinclude:: ../../doc_example/spreadsheet_doc_1.cpp + :language: C++ + :start-after: //!code-start: loader + :end-before: //!code-end: loader + :dedent: 4 + +In this example we are using the :cpp:class:`~orcus::orcus_ods` filter class +because the document we are loading is of Open Document Spreadsheet type, but +the process is the same for other document types, the only difference being +the name of the class. Once the filter object is constructed, we'll simply +load the file by calling its :cpp:func:`~orcus::orcus_ods::read_file` method +and passing the path to the file as its argument: + +.. literalinclude:: ../../doc_example/spreadsheet_doc_1.cpp + :language: C++ + :start-after: //!code-start: read-file + :end-before: //!code-end: read-file + :dedent: 4 + +Once this call returns, the document has been fully populated. What the rest +of the code does is to access the content of the first row of the first sheet of +the document. First, you need to get a reference to the internal cell value +store that we call *model context*: + +.. literalinclude:: ../../doc_example/spreadsheet_doc_1.cpp + :language: C++ + :start-after: //!code-start: model-context + :end-before: //!code-end: model-context + :dedent: 4 + +Since the content of cell A1 is a string, to get the value you need to first +get the ID of the string: + +.. literalinclude:: ../../doc_example/spreadsheet_doc_1.cpp + :language: C++ + :start-after: //!code-start: string-id + :end-before: //!code-end: string-id + :dedent: 4 + +Once you have the ID of the string, you can pass that to the model to get the +actual string value and print it to the standard output: + +.. literalinclude:: ../../doc_example/spreadsheet_doc_1.cpp + :language: C++ + :start-after: //!code-start: print-string + :end-before: //!code-end: print-string + :dedent: 4 + +Here we assume that the string value exists for the given ID. In case you +pass a string ID value to the :cpp:func:`get_string` method and there isn't a string +value associated with it, you'll get a null pointer returned from the call. + +The reason you need to take this 2-step process to get a string value is +because all the string values stored in the cells are pooled at the document +model level, and the cells themselves only store the ID values as integers. + +You may also have noticed that the types surrounding the :cpp:class:`ixion::model_context` +class are all in the :cpp:any:`ixion` namespace. It is because orcus' own +:cpp:class:`~orcus::spreadsheet::document` class uses the formula engine and the +document model from the `ixion library <https://gitlab.com/ixion/ixion>`_ to handle +calculation of the formula cells stored in the document, and the formula engine +requires all cell values to be stored in the :cpp:class:`ixion::model_context` +instance. + +.. note:: The :cpp:class:`~orcus::spreadsheet::document` class in orcus uses + the formula engine from the `ixion library <https://gitlab.com/ixion/ixion>`_ + to calculate the results of the formula cells stored in the document. + +The rest of the code basically repeats the same process for cells B1 and C1: + +.. literalinclude:: ../../doc_example/spreadsheet_doc_1.cpp + :language: C++ + :start-after: //!code-start: rest + :end-before: //!code-end: rest + :dedent: 4 + +and generate the following output: + +.. code-block:: text + + A1: Number + B1: String + C1: Formula + +Accessing the numeric cell values are a bit simpler since the values are +stored directly with the cells. Using the document from the above code example +code, the following code block: + +.. literalinclude:: ../../doc_example/spreadsheet_doc_1_num_and_formula.cpp + :language: C++ + :start-after: //!code-start: print-numeric-cells + :end-before: //!code-end: print-numeric-cells + :dedent: 4 + +will access the cells from A2 through A7 and print out their numeric values. +You should see the following output generated from this code block: + +.. code-block:: text + + A2: 1 + A3: 2 + A4: 3 + A5: 4 + A6: 5 + A7: 6 + +It's a bit more complex to handle formula cells. Since each formula cell +contains two things: 1) the formula expression which is stored as tokens +internally, and 2) the cached result of the formula. The following code +illustrates how to retrieve the cached formula results of cells C2 through +C7: + +.. literalinclude:: ../../doc_example/spreadsheet_doc_1_num_and_formula.cpp + :language: C++ + :start-after: //!code-start: print-formula-cells + :end-before: //!code-end: print-formula-cells + :dedent: 4 + +For each cell, this code first accesses the stored formula cell instance, get +a reference to its cached result, then obtain its string result value to print +it out to the standard output. Running this block of code will produce the +following output: + +.. code-block:: text + + C2: 1 Andy + C3: 2 Bruce + C4: 3 Charlie + C5: 4 David + C6: 5 Edward + C7: 6 Frank + +.. warning:: In production code, you should probabaly check the formula cell + pointer which may be null in case the cell at the specified + position is not a formula cell. |