styles.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. // Copyright (c) 2017-2018 Thomas Fussell
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy
  4. // of this software and associated documentation files (the "Software"), to deal
  5. // in the Software without restriction, including without limitation the rights
  6. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. // copies of the Software, and to permit persons to whom the Software is
  8. // furnished to do so, subject to the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be included in
  11. // all copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. // THE SOFTWARE
  20. //
  21. // @license: http://www.opensource.org/licenses/mit-license.php
  22. // @author: see AUTHORS file
  23. #include <chrono>
  24. #include <string>
  25. #include <iostream>
  26. #include <sstream>
  27. #include <iterator>
  28. #include <random>
  29. #include <helpers/timing.hpp>
  30. #include <xlnt/xlnt.hpp>
  31. namespace {
  32. std::size_t random_index(std::size_t max)
  33. {
  34. static std::random_device rd;
  35. static std::mt19937 gen(rd());
  36. std::uniform_int_distribution<> dis(0, static_cast<int>(max - 1));
  37. return dis(gen);
  38. }
  39. void generate_all_formats(xlnt::workbook &wb, std::vector<xlnt::format>& formats)
  40. {
  41. const auto vertical_alignments = std::vector<xlnt::vertical_alignment>
  42. {
  43. xlnt::vertical_alignment::center,
  44. xlnt::vertical_alignment::justify,
  45. xlnt::vertical_alignment::top,
  46. xlnt::vertical_alignment::bottom
  47. };
  48. const auto horizontal_alignments = std::vector<xlnt::horizontal_alignment>
  49. {
  50. xlnt::horizontal_alignment::center,
  51. xlnt::horizontal_alignment::center_continuous,
  52. xlnt::horizontal_alignment::general,
  53. xlnt::horizontal_alignment::justify,
  54. xlnt::horizontal_alignment::left,
  55. xlnt::horizontal_alignment::right
  56. };
  57. const auto font_names = std::vector<std::string>
  58. {
  59. "Calibri",
  60. "Tahoma",
  61. "Arial",
  62. "Times New Roman"
  63. };
  64. const auto font_sizes = std::vector<double>
  65. {
  66. 11.,
  67. 13.,
  68. 15.,
  69. 17.,
  70. 19.,
  71. 21.,
  72. 23.,
  73. 25.,
  74. 27.,
  75. 29.,
  76. 31.,
  77. 33.,
  78. 35.
  79. };
  80. const auto underline_options = std::vector<xlnt::font::underline_style>
  81. {
  82. xlnt::font::underline_style::single,
  83. xlnt::font::underline_style::none
  84. };
  85. for (auto vertical_alignment : vertical_alignments)
  86. {
  87. for (auto horizontal_alignment : horizontal_alignments)
  88. {
  89. for (auto name : font_names)
  90. {
  91. for (auto size : font_sizes)
  92. {
  93. for (auto bold : { true, false })
  94. {
  95. for (auto underline : underline_options)
  96. {
  97. for (auto italic : { true, false })
  98. {
  99. auto fmt = wb.create_format();
  100. xlnt::font f;
  101. f.name(name);
  102. f.size(size);
  103. f.italic(italic);
  104. f.underline(underline);
  105. f.bold(bold);
  106. fmt.font(f);
  107. xlnt::alignment a;
  108. a.vertical(vertical_alignment);
  109. a.horizontal(horizontal_alignment);
  110. fmt.alignment(a);
  111. formats.push_back(fmt);
  112. }
  113. }
  114. }
  115. }
  116. }
  117. }
  118. }
  119. }
  120. xlnt::workbook non_optimized_workbook_formats(int rows_number, int columns_number)
  121. {
  122. using xlnt::benchmarks::current_time;
  123. xlnt::workbook wb;
  124. std::vector<xlnt::format> formats;
  125. auto start = current_time();
  126. generate_all_formats(wb, formats);
  127. auto elapsed = current_time() - start;
  128. std::cout << "elapsed " << elapsed / 1000.0 << ". generate_all_formats. number of unique formats " << formats.size() << std::endl;
  129. start = current_time();
  130. auto worksheet = wb[random_index(wb.sheet_count())];
  131. auto cells_proceeded = 0;
  132. for (int row_idx = 1; row_idx <= rows_number; row_idx++)
  133. {
  134. for (int col_idx = 1; col_idx <= columns_number; col_idx++)
  135. {
  136. auto cell = worksheet.cell(xlnt::cell_reference((xlnt::column_t)col_idx, (xlnt::row_t)row_idx));
  137. std::ostringstream string_stm;
  138. string_stm << "Col: " << col_idx << "Row: " << row_idx;
  139. cell.value(string_stm.str());
  140. cell.format(formats.at(random_index(formats.size())));
  141. cells_proceeded++;
  142. }
  143. }
  144. elapsed = current_time() - start;
  145. std::cout << "elapsed " << elapsed / 1000.0 << ". set values and formats for cells. cells proceeded " << cells_proceeded << std::endl;
  146. return wb;
  147. }
  148. void to_save_profile(xlnt::workbook &wb, const std::string &f)
  149. {
  150. using xlnt::benchmarks::current_time;
  151. auto start = current_time();
  152. wb.save(f);
  153. auto elapsed = current_time() - start;
  154. std::cout << "elapsed " << elapsed / 1000.0 << ". save workbook." << std::endl;
  155. }
  156. void to_load_profile(xlnt::workbook &wb, const std::string &f)
  157. {
  158. using xlnt::benchmarks::current_time;
  159. auto start = current_time();
  160. wb.load(f);
  161. auto elapsed = current_time() - start;
  162. std::cout << "elapsed " << elapsed / 1000.0 << ". load workbook." << std::endl;
  163. }
  164. void read_formats_profile(xlnt::workbook &wb, int rows_number, int columns_number)
  165. {
  166. using xlnt::benchmarks::current_time;
  167. std::vector<std::string> values;
  168. std::vector<xlnt::format> formats;
  169. auto start = current_time();
  170. auto worksheet = wb[random_index(wb.sheet_count())];
  171. for (int row_idx = 1; row_idx <= rows_number; row_idx++)
  172. {
  173. for (int col_idx = 1; col_idx <= columns_number; col_idx++)
  174. {
  175. auto cell = worksheet.cell(xlnt::cell_reference((xlnt::column_t)col_idx, (xlnt::row_t)row_idx));
  176. values.push_back(cell.value<std::string>());
  177. formats.push_back(cell.format());
  178. }
  179. }
  180. auto elapsed = current_time() - start;
  181. std::cout << "elapsed " << elapsed / 1000.0 << ". read values and formats for cells. values count " << values.size()
  182. << ". formats count " << formats.size() << std::endl;
  183. }
  184. } // namespace
  185. int main(int argc, char * argv[])
  186. {
  187. int rows_number = 1000;
  188. int columns_number = 10;
  189. try
  190. {
  191. if (argc > 1)
  192. rows_number = std::stoi(argv[1]);
  193. if (argc > 2)
  194. columns_number = std::stoi(argv[2]);
  195. std::cout << "started. number of rows " << rows_number << ", number of columns " << columns_number << std::endl;
  196. auto wb = non_optimized_workbook_formats(rows_number, columns_number);
  197. auto f = "temp-formats.xlsx";
  198. to_save_profile(wb, f);
  199. xlnt::workbook load_formats_wb;
  200. to_load_profile(load_formats_wb, f);
  201. read_formats_profile(load_formats_wb, rows_number, columns_number);
  202. }
  203. catch(std::exception& ex)
  204. {
  205. std::cout << "failed. " << ex.what() << std::endl;
  206. }
  207. return 0;
  208. }