differential code coverage report with master
Current view: top level - source/detail/serialization - xlsx_producer.hpp (source / functions) Coverage Total Hit CBC
Current: coverage.info Lines: 100.0 % 28 28 28
Current Date: 2025-12-07 02:01:22 Functions: 100.0 % 31 31 31
Baseline: coverage_master.info Branches: 100.0 % 17 17 34
Baseline Date: 2025-12-07 02:01:21

             Branch data    TLA  Line data    Source code
       1                 :                : // Copyright (c) 2014-2022 Thomas Fussell
       2                 :                : // Copyright (c) 2024-2025 xlnt-community
       3                 :                : //
       4                 :                : // Permission is hereby granted, free of charge, to any person obtaining a copy
       5                 :                : // of this software and associated documentation files (the "Software"), to deal
       6                 :                : // in the Software without restriction, including without limitation the rights
       7                 :                : // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       8                 :                : // copies of the Software, and to permit persons to whom the Software is
       9                 :                : // furnished to do so, subject to the following conditions:
      10                 :                : //
      11                 :                : // The above copyright notice and this permission notice shall be included in
      12                 :                : // all copies or substantial portions of the Software.
      13                 :                : //
      14                 :                : // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      15                 :                : // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      16                 :                : // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      17                 :                : // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      18                 :                : // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      19                 :                : // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      20                 :                : // THE SOFTWARE
      21                 :                : //
      22                 :                : // @license: http://www.opensource.org/licenses/mit-license.php
      23                 :                : // @author: see AUTHORS file
      24                 :                : 
      25                 :                : #pragma once
      26                 :                : 
      27                 :                : #include <iostream>
      28                 :                : #include <memory>
      29                 :                : #include <type_traits>
      30                 :                : #include <vector>
      31                 :                : 
      32                 :                : #include <detail/constants.hpp>
      33                 :                : #include <detail/external/include_libstudxml.hpp>
      34                 :                : #include <detail/serialization/serialisation_helpers.hpp>
      35                 :                : #include <xlnt/internal/features.hpp>
      36                 :                : 
      37                 :                : #if XLNT_HAS_INCLUDE(<string_view>) && XLNT_HAS_FEATURE(U8_STRING_VIEW)
      38                 :                :   #include <string_view>
      39                 :                : #endif
      40                 :                : 
      41                 :                : namespace xml {
      42                 :                : class serializer;
      43                 :                : } // namespace xml
      44                 :                : 
      45                 :                : namespace xlnt {
      46                 :                : 
      47                 :                : class border;
      48                 :                : class cell;
      49                 :                : class cell_reference;
      50                 :                : class color;
      51                 :                : class fill;
      52                 :                : class font;
      53                 :                : class path;
      54                 :                : class relationship;
      55                 :                : class rich_text;
      56                 :                : class streaming_workbook_writer;
      57                 :                : class variant;
      58                 :                : class workbook;
      59                 :                : class worksheet;
      60                 :                : 
      61                 :                : namespace detail {
      62                 :                : 
      63                 :                : class ozstream;
      64                 :                : struct cell_impl;
      65                 :                : struct worksheet_impl;
      66                 :                : 
      67                 :                : /// <summary>
      68                 :                : /// Handles writing a workbook into an XLSX file.
      69                 :                : /// </summary>
      70                 :                : class xlsx_producer
      71                 :                : {
      72                 :                : public:
      73                 :                :         xlsx_producer(const workbook &target);
      74                 :                : 
      75                 :                :     ~xlsx_producer();
      76                 :                : 
      77                 :                :         void write(std::ostream &destination);
      78                 :                : 
      79                 :                :     void write(std::ostream &destination, const std::string &password);
      80                 :                : 
      81                 :                : #if XLNT_HAS_FEATURE(U8_STRING_VIEW)
      82                 :                :     void write(std::ostream &destination, std::u8string_view password);
      83                 :                : #endif
      84                 :                : 
      85                 :                : private:
      86                 :                :     friend class xlnt::streaming_workbook_writer;
      87                 :                : 
      88                 :                :     void open(std::ostream &destination);
      89                 :                : 
      90                 :                :     template <typename T>
      91                 :                :     void write_internal(std::ostream &destination, const T &password);
      92                 :                : 
      93                 :                :     cell add_cell(const cell_reference &ref);
      94                 :                : 
      95                 :                :     worksheet add_worksheet(const std::string &title);
      96                 :                : 
      97                 :                :         /// <summary>
      98                 :                :         /// Write all files needed to create a valid XLSX file which represents all
      99                 :                :         /// data contained in workbook.
     100                 :                :         /// </summary>
     101                 :                :         void populate_archive(bool streaming);
     102                 :                : 
     103                 :                :     void begin_part(const path &part);
     104                 :                :     void end_part();
     105                 :                : 
     106                 :                :         // Package Parts
     107                 :                : 
     108                 :                :         void write_content_types();
     109                 :                :     void write_property(const std::string &name, const variant &value, const std::string &ns, bool custom, std::size_t pid);
     110                 :                :         void write_core_properties(const relationship &rel);
     111                 :                :     void write_extended_properties(const relationship &rel);
     112                 :                :     void write_custom_properties(const relationship &rel);
     113                 :                :     void write_image(const path &image_path);
     114                 :                :     void write_binary(const path &binary_path);
     115                 :                : 
     116                 :                :         // SpreadsheetML-Specific Package Parts
     117                 :                : 
     118                 :                :         void write_workbook(const relationship &rel);
     119                 :                : 
     120                 :                :         // Workbook Relationship Target Parts
     121                 :                : 
     122                 :                :         void write_connections(const relationship &rel);
     123                 :                :         void write_custom_xml_mappings(const relationship &rel);
     124                 :                :         void write_external_workbook_references(const relationship &rel);
     125                 :                :         void write_pivot_table(const relationship &rel);
     126                 :                :         void write_shared_string_table(const relationship &rel);
     127                 :                :         void write_shared_workbook_revision_headers(const relationship &rel);
     128                 :                :         void write_shared_workbook(const relationship &rel);
     129                 :                :         void write_shared_workbook_user_data(const relationship &rel);
     130                 :                :         void write_styles(const relationship &rel);
     131                 :                :         void write_theme(const relationship &rel);
     132                 :                :         void write_volatile_dependencies(const relationship &rel);
     133                 :                : 
     134                 :                :         void write_chartsheet(const relationship &rel);
     135                 :                :         void write_dialogsheet(const relationship &rel);
     136                 :                :         void write_worksheet(const relationship &rel);
     137                 :                : 
     138                 :                :         // Sheet Relationship Target Parts
     139                 :                : 
     140                 :                :         void write_comments(const relationship &rel, worksheet ws, const std::vector<cell_reference> &cells);
     141                 :                :     void write_vml_drawings(const relationship &rel, worksheet ws, const std::vector<cell_reference> &cells);
     142                 :                :     void write_drawings(const relationship &rel, worksheet ws);
     143                 :                : 
     144                 :                :         // Other Parts
     145                 :                : 
     146                 :                :         void write_custom_property();
     147                 :                :         void write_unknown_parts();
     148                 :                :         void write_unknown_relationships();
     149                 :                : 
     150                 :                :         // Helpers
     151                 :                : 
     152                 :                :         /// <summary>
     153                 :                :         /// Some XLSX producers write booleans as "true" or "false" while others use "1" and "0".
     154                 :                :         /// Both are valid, but we can use this method to write either depending on the producer
     155                 :                :         /// we're trying to match.
     156                 :                :         /// </summary>
     157                 :                :         std::string write_bool(bool boolean) const;
     158                 :                : 
     159                 :                :     void write_relationships(const std::vector<xlnt::relationship> &relationships, const path &part);
     160                 :                :     void write_color(const xlnt::color &color);
     161                 :                :     void write_border(const xlnt::border &b);
     162                 :                :         void write_fill(const xlnt::fill &f);
     163                 :                :         void write_font(const xlnt::font &f);
     164                 :                :     void write_table_styles();
     165                 :                :     void write_colors(const std::vector<xlnt::color> &colors);
     166                 :                :     void write_rich_text(const std::string &ns, const xlnt::rich_text &text);
     167                 :                : 
     168                 :                :     template<typename T>
     169                 :CBC        1071 :     void write_element(const std::string &ns, const std::string &name, T value, bool preserve_whitespace = false)
     170                 :                :     {
     171                 :           1071 :         write_start_element(ns, name);
     172         [ +  + ]:           1071 :         write_characters(value, preserve_whitespace);
     173                 :           1071 :         write_end_element(ns, name);
     174                 :           1071 :     }
     175                 :                : 
     176                 :                :     void write_start_element(const std::string &name);
     177                 :                : 
     178                 :                :     void write_start_element(const std::string &ns, const std::string &name);
     179                 :                : 
     180                 :                :     void write_end_element(const std::string &name);
     181                 :                : 
     182                 :                :     void write_end_element(const std::string &ns, const std::string &name);
     183                 :                : 
     184                 :                :     void write_namespace(const std::string &ns, const std::string &prefix);
     185                 :                : 
     186                 :                :     // std::string attribute name
     187                 :                :     // not integer or float type
     188                 :                :     template <typename T, typename = typename std::enable_if<!std::is_convertible<T, double>::value>::type>
     189                 :          21565 :     void write_attribute(const std::string &name, T value)
     190                 :                :     {
     191                 :          21565 :         current_part_serializer_->attribute(name, value);
     192                 :          21565 :     }
     193                 :                : 
     194                 :                :     template <typename T, typename std::enable_if<std::is_floating_point<T>::value, T>::type* = nullptr>
     195                 :            595 :     void write_attribute(const std::string &name, T value)
     196                 :                :     {
     197         [ +  + ]:            595 :         current_part_serializer_->attribute(name, xlnt::detail::serialise(value));
     198                 :            595 :     }
     199                 :                : 
     200                 :                :     template <typename T, typename std::enable_if<std::is_integral<T>::value, T>::type* = nullptr>
     201                 :           9353 :     void write_attribute(const std::string &name, T value)
     202                 :                :     {
     203         [ +  + ]:           9353 :         current_part_serializer_->attribute(name, std::to_string(value));
     204                 :           9353 :     }
     205                 :                : 
     206                 :                :     // qname attribute name
     207                 :                :     // not integer or float type
     208                 :                :     template <typename T, typename = typename std::enable_if<!std::is_convertible<T, double>::value>::type>
     209                 :            293 :     void write_attribute(const xml::qname &name, T value)
     210                 :                :     {
     211                 :            293 :         current_part_serializer_->attribute(name, value);
     212                 :            293 :     }
     213                 :                : 
     214                 :                :     template <typename T, typename std::enable_if<std::is_floating_point<T>::value, T>::type* = nullptr>
     215                 :            280 :     void write_attribute(const xml::qname &name, T value)
     216                 :                :     {
     217         [ +  + ]:            280 :         current_part_serializer_->attribute(name, xlnt::detail::serialise(value));
     218                 :            280 :     }
     219                 :                : 
     220                 :                :     template <typename T, typename std::enable_if<std::is_integral<T>::value, T>::type* = nullptr>
     221                 :             24 :     void write_attribute(const xml::qname &name, T value)
     222                 :                :     {
     223         [ +  + ]:             24 :         current_part_serializer_->attribute(name, std::to_string(value));
     224                 :             24 :     }
     225                 :                : 
     226                 :                : 
     227                 :                :     template <typename T>
     228                 :           2047 :     void write_characters(T characters, bool preserve_whitespace = false)
     229                 :                :     {
     230         [ +  + ]:           2047 :         if (preserve_whitespace)
     231                 :                :         {
     232   [ +  +  +  +  :              8 :             write_attribute(xml::qname(constants::ns("xml"), "space"), "preserve");
                      + ]
     233                 :                :         }
     234                 :                : 
     235                 :           2047 :         current_part_serializer_->characters(characters);
     236                 :           2047 :     }
     237                 :                : 
     238                 :                :         /// <summary>
     239                 :                :         /// A reference to the workbook which is the object of read/write operations.
     240                 :                :         /// </summary>
     241                 :                :         const workbook &source_;
     242                 :                : 
     243                 :                :         std::unique_ptr<ozstream> archive_;
     244                 :                :     std::unique_ptr<xml::serializer> current_part_serializer_;
     245                 :                :     std::unique_ptr<std::streambuf> current_part_streambuf_;
     246                 :                :     std::ostream current_part_stream_;
     247                 :                : 
     248                 :                :     bool streaming_ = false;
     249                 :                : 
     250                 :                :     std::unique_ptr<detail::cell_impl> streaming_cell_;
     251                 :                : 
     252                 :                :     detail::cell_impl *current_cell_ = nullptr;
     253                 :                : 
     254                 :                :     detail::worksheet_impl *current_worksheet_ = nullptr;
     255                 :                : };
     256                 :                : 
     257                 :                : } // namespace detail
     258                 :                : } // namespace xlnt
        

Generated by: LCOV version 2.3.1-beta