worksheet_test_suite.cpp 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679
  1. // Copyright (c) 2014-2021 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 <xlnt/cell/cell.hpp>
  24. #include <xlnt/cell/hyperlink.hpp>
  25. #include <xlnt/workbook/workbook.hpp>
  26. #include <xlnt/worksheet/column_properties.hpp>
  27. #include <xlnt/worksheet/header_footer.hpp>
  28. #include <xlnt/worksheet/range.hpp>
  29. #include <xlnt/worksheet/row_properties.hpp>
  30. #include <xlnt/worksheet/worksheet.hpp>
  31. #include <helpers/test_suite.hpp>
  32. class worksheet_test_suite : public test_suite
  33. {
  34. public:
  35. worksheet_test_suite()
  36. {
  37. register_test(test_new_worksheet);
  38. register_test(test_cell);
  39. register_test(test_invalid_cell);
  40. register_test(test_worksheet_dimension);
  41. register_test(test_fill_rows);
  42. register_test(test_get_named_range);
  43. register_test(test_get_bad_named_range);
  44. register_test(test_get_named_range_wrong_sheet);
  45. register_test(test_remove_named_range_bad);
  46. register_test(test_cell_alternate_coordinates);
  47. register_test(test_cell_range_name);
  48. register_test(test_rows);
  49. register_test(test_no_rows);
  50. register_test(test_no_cols);
  51. register_test(test_one_cell);
  52. register_test(test_cols);
  53. register_test(test_getitem);
  54. register_test(test_setitem);
  55. register_test(test_getslice);
  56. register_test(test_freeze);
  57. register_test(test_merged_cells_lookup);
  58. register_test(test_merged_cell_ranges);
  59. register_test(test_merge_range_string);
  60. register_test(test_unmerge_bad);
  61. register_test(test_unmerge_range_string);
  62. register_test(test_defined_names);
  63. register_test(test_freeze_panes_horiz);
  64. register_test(test_freeze_panes_vert);
  65. register_test(test_freeze_panes_both);
  66. register_test(test_lowest_column);
  67. register_test(test_lowest_column_or_props);
  68. register_test(test_highest_column);
  69. register_test(test_highest_column_or_props);
  70. register_test(test_lowest_row);
  71. register_test(test_lowest_row_or_props);
  72. register_test(test_highest_row);
  73. register_test(test_highest_row_or_props);
  74. register_test(test_iterator_has_value);
  75. register_test(test_const_iterators);
  76. register_test(test_const_reverse_iterators);
  77. register_test(test_column_major_iterators);
  78. register_test(test_reverse_column_major_iterators);
  79. register_test(test_const_column_major_iterators);
  80. register_test(test_const_reverse_column_major_iterators);
  81. register_test(test_header);
  82. register_test(test_footer);
  83. register_test(test_page_setup);
  84. register_test(test_unique_sheet_name);
  85. register_test(test_page_margins);
  86. register_test(test_garbage_collect);
  87. register_test(test_has_cell);
  88. register_test(test_get_range_by_string);
  89. register_test(test_operators);
  90. register_test(test_reserve);
  91. register_test(test_iterate);
  92. register_test(test_range_reference);
  93. register_test(test_get_point_pos);
  94. register_test(test_named_range_named_cell_reference);
  95. register_test(test_iteration_skip_empty);
  96. register_test(test_dimensions);
  97. register_test(test_view_properties_serialization);
  98. register_test(test_clear_cell);
  99. register_test(test_clear_row);
  100. register_test(test_set_title);
  101. register_test(test_set_title_unicode);
  102. register_test(test_phonetics);
  103. register_test(test_insert_rows);
  104. register_test(test_insert_columns);
  105. register_test(test_delete_rows);
  106. register_test(test_delete_columns);
  107. register_test(test_insert_too_many);
  108. register_test(test_insert_delete_moves_merges);
  109. register_test(test_hidden_sheet);
  110. register_test(test_xlsm_read_write);
  111. register_test(test_issue_484);
  112. }
  113. void test_new_worksheet()
  114. {
  115. xlnt::workbook wb;
  116. auto ws = wb.active_sheet();
  117. xlnt_assert(ws.workbook() == wb);
  118. }
  119. void test_cell()
  120. {
  121. xlnt::workbook wb;
  122. auto ws = wb.active_sheet();
  123. auto cell = ws.cell(xlnt::cell_reference(1, 1));
  124. xlnt_assert_equals(cell.reference(), "A1");
  125. }
  126. void test_invalid_cell()
  127. {
  128. xlnt_assert_throws(xlnt::cell_reference(xlnt::column_t((xlnt::column_t::index_t)0), 0),
  129. xlnt::invalid_cell_reference);
  130. }
  131. void test_worksheet_dimension()
  132. {
  133. xlnt::workbook wb;
  134. auto ws = wb.active_sheet();
  135. xlnt_assert_equals("A1:A1", ws.calculate_dimension());
  136. xlnt_assert_equals("A1:A1", ws.calculate_dimension(false));
  137. ws.cell("B12").value("AAA");
  138. xlnt_assert_equals("B12:B12", ws.calculate_dimension());
  139. xlnt_assert_equals("A1:B12", ws.calculate_dimension(false));
  140. }
  141. void test_fill_rows()
  142. {
  143. std::size_t row = 0;
  144. std::size_t column = 0;
  145. std::string coordinate = "A1";
  146. xlnt::workbook wb;
  147. auto ws = wb.active_sheet();
  148. ws.cell("A1").value("first");
  149. ws.cell("C9").value("last");
  150. xlnt_assert_equals(ws.calculate_dimension(), "A1:C9");
  151. xlnt_assert_equals(ws.rows(false)[row][column].reference(), coordinate);
  152. row = 8;
  153. column = 2;
  154. coordinate = "C9";
  155. xlnt_assert_equals(ws.rows(false)[row][column].reference(), coordinate);
  156. }
  157. void test_get_named_range()
  158. {
  159. xlnt::workbook wb;
  160. auto ws = wb.active_sheet();
  161. wb.create_named_range("test_range", ws, "C5");
  162. auto xlrange = ws.named_range("test_range");
  163. xlnt_assert_equals(1, xlrange.length());
  164. xlnt_assert_equals(1, xlrange[0].length());
  165. xlnt_assert_equals(5, xlrange[0][0].row());
  166. ws.create_named_range("test_range2", "C6");
  167. auto xlrange2 = ws.named_range("test_range2");
  168. xlnt_assert_equals(1, xlrange2.length());
  169. xlnt_assert_equals(1, xlrange2[0].length());
  170. xlnt_assert_equals(6, xlrange2[0][0].row());
  171. }
  172. void test_get_bad_named_range()
  173. {
  174. xlnt::workbook wb;
  175. auto ws = wb.active_sheet();
  176. xlnt_assert_throws(ws.named_range("bad_range"), xlnt::key_not_found);
  177. }
  178. void test_get_named_range_wrong_sheet()
  179. {
  180. xlnt::workbook wb;
  181. wb.create_sheet();
  182. wb.create_sheet();
  183. auto ws1 = wb[0];
  184. auto ws2 = wb[1];
  185. wb.create_named_range("wrong_sheet_range", ws1, "C5");
  186. xlnt_assert_throws(ws2.named_range("wrong_sheet_range"), xlnt::key_not_found);
  187. }
  188. void test_remove_named_range_bad()
  189. {
  190. xlnt::workbook wb;
  191. auto ws = wb.active_sheet();
  192. xlnt_assert_throws(ws.remove_named_range("bad_range"), std::runtime_error);
  193. }
  194. void test_cell_alternate_coordinates()
  195. {
  196. xlnt::workbook wb;
  197. auto ws = wb.active_sheet();
  198. auto cell = ws.cell(xlnt::cell_reference(4, 8));
  199. xlnt_assert_equals(cell.reference(), "D8");
  200. }
  201. // void test_cell_insufficient_coordinates() {}
  202. void test_cell_range_name()
  203. {
  204. xlnt::workbook wb;
  205. auto ws = wb.active_sheet();
  206. wb.create_named_range("test_range_single", ws, "B12");
  207. auto c_range_name = ws.named_range("test_range_single");
  208. auto c_range_coord = ws.range("B12");
  209. auto c_cell = ws.cell("B12");
  210. xlnt_assert_equals(c_range_coord, c_range_name);
  211. xlnt_assert(c_range_coord[0][0] == c_cell);
  212. }
  213. void test_rows()
  214. {
  215. xlnt::workbook wb;
  216. auto ws = wb.active_sheet();
  217. ws.cell("A1").value("first");
  218. ws.cell("C9").value("last");
  219. auto rows = ws.rows();
  220. xlnt_assert_equals(rows.length(), 9);
  221. auto first_row = rows[0];
  222. auto last_row = rows[8];
  223. xlnt_assert_equals(first_row[0].value<std::string>(), "first");
  224. xlnt_assert_equals(first_row[0].reference(), "A1");
  225. xlnt_assert_equals(last_row[2].value<std::string>(), "last");
  226. }
  227. void test_no_rows()
  228. {
  229. xlnt::workbook wb;
  230. auto ws = wb.active_sheet();
  231. xlnt_assert_equals(ws.rows().length(), 1);
  232. xlnt_assert_equals(ws.rows()[0].length(), 1);
  233. }
  234. void test_no_cols()
  235. {
  236. xlnt::workbook wb;
  237. auto ws = wb.active_sheet();
  238. xlnt_assert_equals(ws.columns().length(), 1);
  239. xlnt_assert_equals(ws.columns()[0].length(), 1);
  240. }
  241. void test_one_cell()
  242. {
  243. xlnt::workbook wb;
  244. auto ws = wb.active_sheet();
  245. auto cell = ws.cell("A1");
  246. xlnt_assert_equals(ws.columns().length(), 1);
  247. xlnt_assert_equals(ws.columns()[0].length(), 1);
  248. xlnt_assert_equals(ws.columns()[0][0], cell);
  249. }
  250. // void test_by_col() {}
  251. void test_cols()
  252. {
  253. xlnt::workbook wb;
  254. auto ws = wb.active_sheet();
  255. ws.cell("A1").value("first");
  256. ws.cell("C9").value("last");
  257. auto cols = ws.columns();
  258. xlnt_assert_equals(cols.length(), 3);
  259. xlnt_assert_equals(cols[0][0].value<std::string>(), "first");
  260. xlnt_assert_equals(cols[2][8].value<std::string>(), "last");
  261. }
  262. void test_getitem()
  263. {
  264. xlnt::workbook wb;
  265. auto ws = wb.active_sheet();
  266. xlnt::cell cell = ws[xlnt::cell_reference("A1")];
  267. xlnt_assert_equals(cell.reference().to_string(), "A1");
  268. xlnt_assert_equals(cell.data_type(), xlnt::cell::type::empty);
  269. }
  270. void test_setitem()
  271. {
  272. xlnt::workbook wb;
  273. auto ws = wb.active_sheet();
  274. ws[xlnt::cell_reference("A12")].value(5);
  275. xlnt_assert(ws[xlnt::cell_reference("A12")].value<int>() == 5);
  276. }
  277. void test_getslice()
  278. {
  279. xlnt::workbook wb;
  280. auto ws = wb.active_sheet();
  281. auto cell_range = ws.range("A1:B2");
  282. xlnt_assert_equals(cell_range[0][0], ws.cell("A1"));
  283. xlnt_assert_equals(cell_range[1][0], ws.cell("A2"));
  284. xlnt_assert_equals(cell_range[0][1], ws.cell("B1"));
  285. xlnt_assert_equals(cell_range[1][1], ws.cell("B2"));
  286. }
  287. void test_freeze()
  288. {
  289. xlnt::workbook wb;
  290. auto ws = wb.active_sheet();
  291. ws.freeze_panes(ws.cell("b2"));
  292. xlnt_assert_equals(ws.frozen_panes(), "B2");
  293. ws.unfreeze_panes();
  294. xlnt_assert(!ws.has_frozen_panes());
  295. ws.freeze_panes("c5");
  296. xlnt_assert_equals(ws.frozen_panes(), "C5");
  297. ws.freeze_panes(ws.cell("A1"));
  298. xlnt_assert(!ws.has_frozen_panes());
  299. }
  300. void test_merged_cells_lookup()
  301. {
  302. xlnt::workbook wb;
  303. auto ws = wb.active_sheet();
  304. ws.cell("A2").value("test");
  305. ws.merge_cells("A1:N50");
  306. auto all_merged = ws.merged_ranges();
  307. xlnt_assert_equals(all_merged.size(), 1);
  308. auto merged = ws.range(all_merged[0]);
  309. xlnt_assert(merged.contains("A1"));
  310. xlnt_assert(merged.contains("N50"));
  311. xlnt_assert(!merged.contains("A51"));
  312. xlnt_assert(!merged.contains("O1"));
  313. }
  314. void test_merged_cell_ranges()
  315. {
  316. xlnt::workbook wb;
  317. auto ws = wb.active_sheet();
  318. xlnt_assert_equals(ws.merged_ranges().size(), 0);
  319. }
  320. void test_merge_range_string()
  321. {
  322. xlnt::workbook wb;
  323. auto ws = wb.active_sheet();
  324. ws.cell("A1").value(1);
  325. ws.cell("D4").value(16);
  326. ws.merge_cells("A1:D4");
  327. std::vector<xlnt::range_reference> expected = {xlnt::range_reference("A1:D4")};
  328. xlnt_assert_equals(ws.merged_ranges(), expected);
  329. xlnt_assert(!ws.cell("D4").has_value());
  330. }
  331. void test_unmerge_bad()
  332. {
  333. xlnt::workbook wb;
  334. auto ws = wb.active_sheet();
  335. xlnt_assert_throws(ws.unmerge_cells("A1:D3"), std::runtime_error);
  336. }
  337. void test_unmerge_range_string()
  338. {
  339. xlnt::workbook wb;
  340. auto ws = wb.active_sheet();
  341. ws.merge_cells("A1:D4");
  342. xlnt_assert_equals(ws.merged_ranges().size(), 1);
  343. ws.unmerge_cells("A1:D4");
  344. xlnt_assert_equals(ws.merged_ranges().size(), 0);
  345. }
  346. void test_defined_names()
  347. {
  348. xlnt::workbook wb;
  349. wb.load(path_helper::test_file("19_defined_names.xlsx"));
  350. auto ws1 = wb.sheet_by_index(0);
  351. xlnt_assert(!ws1.has_print_area());
  352. xlnt_assert(ws1.has_auto_filter());
  353. xlnt_assert_equals(ws1.auto_filter().to_string(), "A1:A6");
  354. xlnt_assert(ws1.has_print_titles());
  355. xlnt_assert(!ws1.print_title_cols().is_set());
  356. xlnt_assert(ws1.print_title_rows().is_set());
  357. xlnt_assert_equals(ws1.print_title_rows().get().first, 1);
  358. xlnt_assert_equals(ws1.print_title_rows().get().second, 3);
  359. auto ws2 = wb.sheet_by_index(1);
  360. xlnt_assert(ws2.has_print_area());
  361. xlnt_assert_equals(ws2.print_area().to_string(), "$B$4:$B$4");
  362. xlnt_assert(!ws2.has_auto_filter());
  363. xlnt_assert(ws2.has_print_titles());
  364. xlnt_assert(!ws2.print_title_rows().is_set());
  365. xlnt_assert(ws2.print_title_cols().is_set());
  366. xlnt_assert_equals(ws2.print_title_cols().get().first, "A");
  367. xlnt_assert_equals(ws2.print_title_cols().get().second, "D");
  368. auto ws3 = wb.sheet_by_index(2);
  369. xlnt_assert(ws3.has_print_area());
  370. xlnt_assert_equals(ws3.print_area().to_string(), "$B$2:$E$4");
  371. xlnt_assert(!ws3.has_auto_filter());
  372. xlnt_assert(ws3.has_print_titles());
  373. xlnt_assert(ws3.print_title_rows().is_set());
  374. xlnt_assert(ws3.print_title_cols().is_set());
  375. xlnt_assert_equals(ws3.print_title_cols().get().first, "B");
  376. xlnt_assert_equals(ws3.print_title_cols().get().second, "E");
  377. xlnt_assert_equals(ws3.print_title_rows().get().first, 2);
  378. xlnt_assert_equals(ws3.print_title_rows().get().second, 4);
  379. wb.save("titles1.xlsx");
  380. }
  381. void test_freeze_panes_horiz()
  382. {
  383. xlnt::workbook wb;
  384. auto ws = wb.active_sheet();
  385. ws.freeze_panes("A4");
  386. auto view = ws.view();
  387. xlnt_assert_equals(view.selections().size(), 1);
  388. // pane is the corner of the worksheet that this selection extends to
  389. // active cell is the last selected cell in the selection
  390. // sqref is the last selected block in the selection
  391. xlnt_assert_equals(view.selections()[0].pane(), xlnt::pane_corner::bottom_left);
  392. xlnt_assert_equals(view.selections()[0].active_cell(), "A4");
  393. xlnt_assert_equals(view.selections()[0].sqref(), "A4");
  394. xlnt_assert_equals(view.pane().active_pane, xlnt::pane_corner::bottom_left);
  395. xlnt_assert_equals(view.pane().state, xlnt::pane_state::frozen);
  396. xlnt_assert_equals(view.pane().top_left_cell.get(), "A4");
  397. xlnt_assert_equals(view.pane().y_split, 3);
  398. }
  399. void test_freeze_panes_vert()
  400. {
  401. xlnt::workbook wb;
  402. auto ws = wb.active_sheet();
  403. ws.freeze_panes("D1");
  404. auto view = ws.view();
  405. xlnt_assert_equals(view.selections().size(), 1);
  406. // pane is the corner of the worksheet that this selection extends to
  407. // active cell is the last selected cell in the selection
  408. // sqref is the last selected block in the selection
  409. xlnt_assert_equals(view.selections()[0].pane(), xlnt::pane_corner::top_right);
  410. xlnt_assert_equals(view.selections()[0].active_cell(), "D1");
  411. xlnt_assert_equals(view.selections()[0].sqref(), "D1");
  412. xlnt_assert_equals(view.pane().active_pane, xlnt::pane_corner::top_right);
  413. xlnt_assert_equals(view.pane().state, xlnt::pane_state::frozen);
  414. xlnt_assert_equals(view.pane().top_left_cell.get(), "D1");
  415. xlnt_assert_equals(view.pane().x_split, 3);
  416. }
  417. void test_freeze_panes_both()
  418. {
  419. xlnt::workbook wb;
  420. auto ws = wb.active_sheet();
  421. ws.freeze_panes("D4");
  422. auto view = ws.view();
  423. xlnt_assert_equals(view.selections().size(), 3);
  424. // pane is the corner of the worksheet that this selection extends to
  425. // active cell is the last selected cell in the selection
  426. // sqref is the last selected block in the selection
  427. xlnt_assert_equals(view.selections()[0].pane(), xlnt::pane_corner::top_right);
  428. xlnt_assert_equals(view.selections()[0].active_cell(), "D1");
  429. xlnt_assert_equals(view.selections()[0].sqref(), "D1");
  430. xlnt_assert_equals(view.selections()[1].pane(), xlnt::pane_corner::bottom_left);
  431. xlnt_assert_equals(view.selections()[1].active_cell(), "A4");
  432. xlnt_assert_equals(view.selections()[1].sqref(), "A4");
  433. xlnt_assert_equals(view.selections()[2].pane(), xlnt::pane_corner::bottom_right);
  434. xlnt_assert_equals(view.selections()[2].active_cell(), "D4");
  435. xlnt_assert_equals(view.selections()[2].sqref(), "D4");
  436. xlnt_assert_equals(view.pane().active_pane, xlnt::pane_corner::bottom_right);
  437. xlnt_assert_equals(view.pane().state, xlnt::pane_state::frozen);
  438. xlnt_assert_equals(view.pane().top_left_cell.get(), "D4");
  439. xlnt_assert_equals(view.pane().x_split, 3);
  440. xlnt_assert_equals(view.pane().y_split, 3);
  441. }
  442. void test_lowest_column()
  443. {
  444. xlnt::workbook wb;
  445. auto ws = wb.active_sheet();
  446. xlnt_assert_equals(ws.lowest_column(), 1);
  447. }
  448. void test_lowest_column_or_props()
  449. {
  450. xlnt::workbook wb;
  451. auto ws = wb.active_sheet();
  452. ws.column_properties("J").width = 14.3;
  453. xlnt_assert_equals(ws.lowest_column_or_props(), "J");
  454. }
  455. void test_highest_column()
  456. {
  457. xlnt::workbook wb;
  458. auto ws = wb.active_sheet();
  459. ws[xlnt::cell_reference("F1")].value(10);
  460. ws[xlnt::cell_reference("F2")].value(32);
  461. ws[xlnt::cell_reference("F3")].formula("=F1+F2");
  462. ws[xlnt::cell_reference("A4")].formula("=A1+A2+A3");
  463. xlnt_assert_equals(ws.highest_column(), "F");
  464. }
  465. void test_highest_column_or_props()
  466. {
  467. xlnt::workbook wb;
  468. auto ws = wb.active_sheet();
  469. ws.column_properties("J").width = 14.3;
  470. xlnt_assert_equals(ws.highest_column_or_props(), "J");
  471. }
  472. void test_lowest_row()
  473. {
  474. xlnt::workbook wb;
  475. auto ws = wb.active_sheet();
  476. xlnt_assert_equals(ws.lowest_row(), 1);
  477. }
  478. void test_lowest_row_or_props()
  479. {
  480. xlnt::workbook wb;
  481. auto ws = wb.active_sheet();
  482. ws.row_properties(11).height = 14.3;
  483. xlnt_assert_equals(ws.lowest_row_or_props(), 11);
  484. }
  485. void test_highest_row()
  486. {
  487. xlnt::workbook wb;
  488. auto ws = wb.active_sheet();
  489. ws.cell("D4").value("D4");
  490. xlnt_assert_equals(ws.highest_row(), 4);
  491. }
  492. void test_highest_row_or_props()
  493. {
  494. xlnt::workbook wb;
  495. auto ws = wb.active_sheet();
  496. ws.row_properties(11).height = 14.3;
  497. xlnt_assert_equals(ws.highest_row_or_props(), 11);
  498. }
  499. void test_iterator_has_value()
  500. {
  501. xlnt::workbook wb;
  502. auto ws = wb.active_sheet();
  503. // make a worksheet with a blank row and column
  504. ws.cell("A1").value("A1");
  505. ws.cell("A3").value("A3");
  506. ws.cell("C1").value("C1");
  507. xlnt_assert_equals(ws.columns(false)[0].begin().has_value(), true);
  508. xlnt_assert_equals(ws.rows(false)[0].begin().has_value(), true);
  509. xlnt_assert_equals(ws.columns(false)[1].begin().has_value(), false);
  510. xlnt_assert_equals(ws.rows(false)[1].begin().has_value(), false);
  511. // also test const interators.
  512. xlnt_assert_equals(ws.columns(false)[0].cbegin().has_value(), true);
  513. xlnt_assert_equals(ws.rows(false)[0].cbegin().has_value(), true);
  514. xlnt_assert_equals(ws.columns(false)[1].cbegin().has_value(), false);
  515. xlnt_assert_equals(ws.rows(false)[1].cbegin().has_value(), false);
  516. }
  517. void test_const_iterators()
  518. {
  519. xlnt::workbook wb;
  520. auto ws = wb.active_sheet();
  521. ws.cell("A1").value("A1");
  522. ws.cell("B1").value("B1");
  523. ws.cell("C1").value("C1");
  524. ws.cell("A2").value("A2");
  525. ws.cell("B2").value("B2");
  526. ws.cell("C2").value("C2");
  527. const xlnt::worksheet ws_const = ws;
  528. const auto rows = ws_const.rows();
  529. const auto first_row = rows.front();
  530. const auto first_cell = first_row.front();
  531. xlnt_assert_equals(first_cell.reference(), "A1");
  532. xlnt_assert_equals(first_cell.value<std::string>(), "A1");
  533. const auto last_row = rows.back();
  534. const auto last_cell = last_row.back();
  535. xlnt_assert_equals(last_cell.reference(), "C2");
  536. xlnt_assert_equals(last_cell.value<std::string>(), "C2");
  537. for (const auto row : rows)
  538. {
  539. for (const auto cell : row)
  540. {
  541. xlnt_assert_equals(cell.value<std::string>(), cell.reference().to_string());
  542. }
  543. }
  544. xlnt_assert_equals(xlnt::const_cell_iterator{}, xlnt::const_cell_iterator{});
  545. xlnt_assert_equals(xlnt::const_range_iterator{}, xlnt::const_range_iterator{});
  546. }
  547. void test_const_reverse_iterators()
  548. {
  549. xlnt::workbook wb;
  550. auto ws = wb.active_sheet();
  551. ws.cell("A1").value("A1");
  552. ws.cell("B1").value("B1");
  553. ws.cell("C1").value("C1");
  554. ws.cell("A2").value("A2");
  555. ws.cell("B2").value("B2");
  556. ws.cell("C2").value("C2");
  557. const xlnt::worksheet ws_const = ws;
  558. const auto rows = ws_const.rows();
  559. const auto first_row = *rows.rbegin();
  560. const auto first_cell = *first_row.rbegin();
  561. xlnt_assert_equals(first_cell.value<std::string>(), "C2");
  562. auto row_iter = rows.rend();
  563. row_iter--;
  564. const auto last_row = *row_iter;
  565. auto cell_iter = last_row.rend();
  566. cell_iter--;
  567. const auto last_cell = *cell_iter;
  568. xlnt_assert_equals(last_cell.value<std::string>(), "A1");
  569. for (auto ws_iter = rows.rbegin(); ws_iter != rows.rend(); ws_iter++)
  570. {
  571. const auto row = *ws_iter;
  572. for (auto row_iter = row.rbegin(); row_iter != row.rend(); row_iter++)
  573. {
  574. const auto cell = *row_iter;
  575. xlnt_assert_equals(cell.value<std::string>(), cell.reference().to_string());
  576. }
  577. }
  578. }
  579. void test_column_major_iterators()
  580. {
  581. xlnt::workbook wb;
  582. auto ws = wb.active_sheet();
  583. ws.cell("A1").value("A1");
  584. ws.cell("B1").value("B1");
  585. ws.cell("C1").value("C1");
  586. ws.cell("A2").value("A2");
  587. ws.cell("B2").value("B2");
  588. ws.cell("C2").value("C2");
  589. auto columns = ws.columns();
  590. auto first_column = *columns.begin();
  591. auto first_column_iter = first_column.begin();
  592. auto first_cell = *first_column_iter;
  593. xlnt_assert_equals(first_cell.value<std::string>(), "A1");
  594. first_column_iter++;
  595. auto second_cell = *first_column_iter;
  596. xlnt_assert_equals(second_cell.value<std::string>(), "A2");
  597. xlnt_assert_equals(first_cell, first_column.front());
  598. xlnt_assert_equals(second_cell, first_column.back());
  599. auto last_column = *(--columns.end());
  600. auto last_column_iter = last_column.end();
  601. last_column_iter--;
  602. auto last_cell = *last_column_iter;
  603. xlnt_assert_equals(last_cell.value<std::string>(), "C2");
  604. last_column_iter--;
  605. auto penultimate_cell = *last_column_iter;
  606. xlnt_assert_equals(penultimate_cell.value<std::string>(), "C1");
  607. for (auto column : columns)
  608. {
  609. for (auto cell : column)
  610. {
  611. xlnt_assert_equals(cell.value<std::string>(), cell.reference().to_string());
  612. }
  613. }
  614. }
  615. void test_reverse_column_major_iterators()
  616. {
  617. xlnt::workbook wb;
  618. auto ws = wb.active_sheet();
  619. ws.cell("A1").value("A1");
  620. ws.cell("B1").value("B1");
  621. ws.cell("C1").value("C1");
  622. ws.cell("A2").value("A2");
  623. ws.cell("B2").value("B2");
  624. ws.cell("C2").value("C2");
  625. auto columns = ws.columns();
  626. auto column_iter = columns.rbegin();
  627. auto first_column = *column_iter;
  628. auto first_column_iter = first_column.rbegin();
  629. auto first_cell = *first_column_iter;
  630. xlnt_assert_equals(first_cell.value<std::string>(), "C2");
  631. first_column_iter++;
  632. auto second_cell = *first_column_iter;
  633. xlnt_assert_equals(second_cell.value<std::string>(), "C1");
  634. auto last_column = *(--columns.rend());
  635. auto last_column_iter = last_column.rend();
  636. last_column_iter--;
  637. auto last_cell = *last_column_iter;
  638. xlnt_assert_equals(last_cell.value<std::string>(), "A1");
  639. last_column_iter--;
  640. auto penultimate_cell = *last_column_iter;
  641. xlnt_assert_equals(penultimate_cell.value<std::string>(), "A2");
  642. for (auto column_iter = columns.rbegin(); column_iter != columns.rend(); ++column_iter)
  643. {
  644. auto column = *column_iter;
  645. for (auto cell_iter = column.rbegin(); cell_iter != column.rend(); ++cell_iter)
  646. {
  647. auto cell = *cell_iter;
  648. xlnt_assert_equals(cell.value<std::string>(), cell.reference().to_string());
  649. }
  650. }
  651. }
  652. void test_const_column_major_iterators()
  653. {
  654. xlnt::workbook wb;
  655. auto ws = wb.active_sheet();
  656. ws.cell("A1").value("A1");
  657. ws.cell("B1").value("B1");
  658. ws.cell("C1").value("C1");
  659. ws.cell("A2").value("A2");
  660. ws.cell("B2").value("B2");
  661. ws.cell("C2").value("C2");
  662. const xlnt::worksheet ws_const = ws;
  663. const auto columns = ws_const.columns();
  664. const auto first_column = *columns.begin();
  665. auto first_column_iter = first_column.begin();
  666. const auto first_cell = *first_column_iter;
  667. xlnt_assert_equals(first_cell.value<std::string>(), "A1");
  668. first_column_iter++;
  669. const auto second_cell = *first_column_iter;
  670. xlnt_assert_equals(second_cell.value<std::string>(), "A2");
  671. const auto last_column = *(--columns.end());
  672. auto last_column_iter = last_column.end();
  673. last_column_iter--;
  674. const auto last_cell = *last_column_iter;
  675. xlnt_assert_equals(last_cell.value<std::string>(), "C2");
  676. last_column_iter--;
  677. const auto penultimate_cell = *last_column_iter;
  678. xlnt_assert_equals(penultimate_cell.value<std::string>(), "C1");
  679. for (const auto column : columns)
  680. {
  681. for (const auto cell : column)
  682. {
  683. xlnt_assert_equals(cell.value<std::string>(), cell.reference().to_string());
  684. }
  685. }
  686. }
  687. void test_const_reverse_column_major_iterators()
  688. {
  689. xlnt::workbook wb;
  690. auto ws = wb.active_sheet();
  691. ws.cell("A1").value("A1");
  692. ws.cell("B1").value("B1");
  693. ws.cell("C1").value("C1");
  694. ws.cell("A2").value("A2");
  695. ws.cell("B2").value("B2");
  696. ws.cell("C2").value("C2");
  697. const xlnt::worksheet ws_const = ws;
  698. const auto columns = ws_const.columns();
  699. const auto first_column = *columns.crbegin();
  700. auto first_column_iter = first_column.crbegin();
  701. const auto first_cell = *first_column_iter;
  702. xlnt_assert_equals(first_cell.value<std::string>(), "C2");
  703. first_column_iter++;
  704. const auto second_cell = *first_column_iter;
  705. xlnt_assert_equals(second_cell.value<std::string>(), "C1");
  706. const auto last_column = *(--columns.crend());
  707. auto last_column_iter = last_column.crend();
  708. last_column_iter--;
  709. const auto last_cell = *last_column_iter;
  710. xlnt_assert_equals(last_cell.value<std::string>(), "A1");
  711. last_column_iter--;
  712. const auto penultimate_cell = *last_column_iter;
  713. xlnt_assert_equals(penultimate_cell.value<std::string>(), "A2");
  714. for (auto column_iter = columns.crbegin(); column_iter != columns.crend(); ++column_iter)
  715. {
  716. const auto column = *column_iter;
  717. for (auto cell_iter = column.crbegin(); cell_iter != column.crend(); ++cell_iter)
  718. {
  719. const auto cell = *cell_iter;
  720. xlnt_assert_equals(cell.value<std::string>(), cell.reference().to_string());
  721. }
  722. }
  723. }
  724. void test_header()
  725. {
  726. xlnt::header_footer hf;
  727. using hf_loc = xlnt::header_footer::location;
  728. for (auto location : {hf_loc::left, hf_loc::center, hf_loc::right})
  729. {
  730. xlnt_assert(!hf.has_header(location));
  731. xlnt_assert(!hf.has_odd_even_header(location));
  732. xlnt_assert(!hf.has_first_page_header(location));
  733. hf.header(location, "abc");
  734. xlnt_assert(hf.has_header(location));
  735. xlnt_assert(!hf.has_odd_even_header(location));
  736. xlnt_assert(!hf.has_first_page_header(location));
  737. xlnt_assert_equals(hf.header(location), "abc");
  738. hf.clear_header(location);
  739. xlnt_assert(!hf.has_header(location));
  740. }
  741. }
  742. void test_footer()
  743. {
  744. xlnt::header_footer hf;
  745. using hf_loc = xlnt::header_footer::location;
  746. for (auto location : {hf_loc::left, hf_loc::center, hf_loc::right})
  747. {
  748. xlnt_assert(!hf.has_footer(location));
  749. xlnt_assert(!hf.has_odd_even_footer(location));
  750. xlnt_assert(!hf.has_first_page_footer(location));
  751. hf.footer(location, "abc");
  752. xlnt_assert(hf.has_footer(location));
  753. xlnt_assert(!hf.has_odd_even_footer(location));
  754. xlnt_assert(!hf.has_first_page_footer(location));
  755. xlnt_assert_equals(hf.footer(location), "abc");
  756. hf.clear_footer(location);
  757. xlnt_assert(!hf.has_footer(location));
  758. }
  759. }
  760. void test_page_setup()
  761. {
  762. xlnt::page_setup setup;
  763. setup.page_break(xlnt::page_break::column);
  764. xlnt_assert_equals(setup.page_break(), xlnt::page_break::column);
  765. setup.scale(1.23);
  766. xlnt_assert_equals(setup.scale(), 1.23);
  767. }
  768. void test_unique_sheet_name()
  769. {
  770. xlnt::workbook wb;
  771. auto first_created = wb.create_sheet();
  772. auto second_created = wb.create_sheet();
  773. xlnt_assert_differs(first_created.title(), second_created.title());
  774. }
  775. void test_page_margins()
  776. {
  777. xlnt::workbook wb;
  778. auto ws = wb.active_sheet();
  779. auto margins = ws.page_margins();
  780. margins.top(0);
  781. margins.bottom(1);
  782. margins.header(2);
  783. margins.footer(3);
  784. margins.left(4);
  785. margins.right(5);
  786. ws.page_margins(margins);
  787. xlnt_assert(ws.has_page_margins());
  788. xlnt_assert_equals(ws.page_margins().top(), 0);
  789. xlnt_assert_equals(ws.page_margins().bottom(), 1);
  790. xlnt_assert_equals(ws.page_margins().header(), 2);
  791. xlnt_assert_equals(ws.page_margins().footer(), 3);
  792. xlnt_assert_equals(ws.page_margins().left(), 4);
  793. xlnt_assert_equals(ws.page_margins().right(), 5);
  794. }
  795. void test_garbage_collect()
  796. {
  797. xlnt::workbook wb;
  798. auto ws = wb.active_sheet();
  799. auto dimensions = ws.calculate_dimension();
  800. xlnt_assert_equals(dimensions, xlnt::range_reference("A1", "A1"));
  801. ws.cell("B2").value("text");
  802. ws.garbage_collect();
  803. dimensions = ws.calculate_dimension();
  804. xlnt_assert_equals(dimensions, xlnt::range_reference("B2", "B2"));
  805. }
  806. void test_has_cell()
  807. {
  808. xlnt::workbook wb;
  809. auto ws = wb.active_sheet();
  810. ws.cell("A3").value("test");
  811. xlnt_assert(!ws.has_cell("A2"));
  812. xlnt_assert(ws.has_cell("A3"));
  813. }
  814. void test_get_range_by_string()
  815. {
  816. xlnt::workbook wb;
  817. auto ws = wb.active_sheet();
  818. ws.cell("A2").value(3.14);
  819. ws.cell("A3").value(true);
  820. ws.cell("B2").value("text");
  821. ws.cell("B3").value(false);
  822. auto range = ws.range("A2:B3");
  823. auto range_iter = range.begin();
  824. auto row = *range_iter;
  825. auto row_iter = row.begin();
  826. xlnt_assert_equals((*row_iter).value<double>(), 3.14);
  827. xlnt_assert_equals((*row_iter).reference(), "A2");
  828. xlnt_assert_equals((*row_iter), row.front());
  829. row_iter++;
  830. xlnt_assert_equals((*row_iter).value<std::string>(), "text");
  831. xlnt_assert_equals((*row_iter).reference(), "B2");
  832. xlnt_assert_equals((*row_iter), row.back());
  833. range_iter++;
  834. row = *range_iter;
  835. row_iter = row.begin();
  836. xlnt_assert_equals((*row_iter).value<bool>(), true);
  837. xlnt_assert_equals((*row_iter).reference(), "A3");
  838. range_iter = range.end();
  839. range_iter--;
  840. row = *range_iter;
  841. row_iter = row.end();
  842. row_iter--;
  843. xlnt_assert_equals((*row_iter).value<bool>(), false);
  844. }
  845. void test_operators()
  846. {
  847. xlnt::workbook wb;
  848. wb.create_sheet();
  849. wb.create_sheet();
  850. auto ws1 = wb[1];
  851. auto ws2 = wb[2];
  852. xlnt_assert_differs(ws1, ws2);
  853. ws1[xlnt::cell_reference("A2")].value(true);
  854. xlnt_assert_equals(ws1[xlnt::cell_reference("A2")].value<bool>(), true);
  855. xlnt_assert_equals((*(*ws1.range("A2:A2").begin()).begin()).value<bool>(), true);
  856. ws1.create_named_range("rangey", "A2:A2");
  857. xlnt_assert_equals(ws1.range("rangey"), ws1.range("A2:A2"));
  858. xlnt_assert_equals(ws1.range("A2:A2"), ws1.range("A2:A2"));
  859. xlnt_assert(ws1.range("rangey") != ws1.range("A2:A3"));
  860. xlnt_assert_equals(ws1.range("rangey").cell("A1"), ws1.cell("A2"));
  861. }
  862. void test_reserve()
  863. {
  864. xlnt::workbook wb;
  865. auto ws = wb.active_sheet();
  866. ws.reserve(1000);
  867. //TODO: actual tests go here
  868. }
  869. void test_iterate()
  870. {
  871. xlnt::workbook wb;
  872. auto ws = wb.active_sheet();
  873. ws.cell("B3").value("B3");
  874. ws.cell("C7").value("C7");
  875. for (auto row : ws)
  876. {
  877. for (auto cell : row)
  878. {
  879. if (cell.has_value())
  880. {
  881. xlnt_assert_equals(cell.reference().to_string(), cell.value<std::string>());
  882. }
  883. }
  884. }
  885. const auto ws_const = ws;
  886. for (auto row : ws_const)
  887. {
  888. for (auto cell : row)
  889. {
  890. if (cell.has_value())
  891. {
  892. xlnt_assert_equals(cell.reference().to_string(), cell.value<std::string>());
  893. }
  894. }
  895. }
  896. const auto const_range = ws_const.range("B3:C7");
  897. auto const_range_iter = const_range.cbegin();
  898. const_range_iter++;
  899. const_range_iter--;
  900. xlnt_assert_equals(const_range_iter, const_range.begin());
  901. xlnt_assert_equals(xlnt::cell_iterator{}, xlnt::cell_iterator{});
  902. xlnt_assert_equals(xlnt::range_iterator{}, xlnt::range_iterator{});
  903. }
  904. void test_range_reference()
  905. {
  906. xlnt::range_reference ref1("A1:A1");
  907. xlnt_assert(ref1.is_single_cell());
  908. xlnt::range_reference ref2("A1:B2");
  909. xlnt_assert(!ref2.is_single_cell());
  910. xlnt_assert(ref1 == xlnt::range_reference("A1:A1"));
  911. xlnt_assert(ref1 != ref2);
  912. xlnt_assert(ref1 == "A1:A1");
  913. xlnt_assert(ref1 == std::string("A1:A1"));
  914. xlnt_assert(std::string("A1:A1") == ref1);
  915. xlnt_assert("A1:A1" == ref1);
  916. xlnt_assert(ref1 != "A1:B2");
  917. xlnt_assert(ref1 != std::string("A1:B2"));
  918. xlnt_assert(std::string("A1:B2") != ref1);
  919. xlnt_assert("A1:B2" != ref1);
  920. }
  921. void test_get_point_pos()
  922. {
  923. xlnt::workbook wb;
  924. auto ws = wb.active_sheet();
  925. xlnt_assert_equals(ws.point_pos(0, 0), "A1");
  926. }
  927. void test_named_range_named_cell_reference()
  928. {
  929. xlnt::workbook wb;
  930. auto ws = wb.active_sheet();
  931. xlnt_assert_throws(ws.create_named_range("A1", "A2"), xlnt::invalid_parameter);
  932. xlnt_assert_throws(ws.create_named_range("XFD1048576", "A2"), xlnt::invalid_parameter);
  933. xlnt_assert_throws_nothing(ws.create_named_range("XFE1048576", "A2"));
  934. xlnt_assert_throws_nothing(ws.create_named_range("XFD1048577", "A2"));
  935. }
  936. void test_iteration_skip_empty()
  937. {
  938. xlnt::workbook wb;
  939. auto ws = wb.active_sheet();
  940. ws.cell("A1").value("A1");
  941. ws.cell("F6").value("F6");
  942. {
  943. std::vector<xlnt::cell> cells;
  944. for (auto row : ws)
  945. {
  946. for (auto cell : row)
  947. {
  948. cells.push_back(cell);
  949. }
  950. }
  951. xlnt_assert_equals(cells.size(), 2);
  952. xlnt_assert_equals(cells[0].value<std::string>(), "A1");
  953. xlnt_assert_equals(cells[1].value<std::string>(), "F6");
  954. }
  955. const auto ws_const = ws;
  956. {
  957. std::vector<xlnt::cell> cells;
  958. for (auto row : ws_const)
  959. {
  960. for (auto cell : row)
  961. {
  962. cells.push_back(cell);
  963. }
  964. }
  965. xlnt_assert_equals(cells.size(), 2);
  966. xlnt_assert_equals(cells[0].value<std::string>(), "A1");
  967. xlnt_assert_equals(cells[1].value<std::string>(), "F6");
  968. }
  969. }
  970. void test_dimensions()
  971. {
  972. xlnt::workbook workbook;
  973. workbook.load(path_helper::test_file("4_every_style.xlsx"));
  974. auto active_sheet = workbook.active_sheet();
  975. auto sheet_range = active_sheet.calculate_dimension();
  976. xlnt_assert(!sheet_range.is_single_cell());
  977. xlnt_assert_equals(sheet_range.width(), 4);
  978. xlnt_assert_equals(sheet_range.height(), 35);
  979. }
  980. void test_view_properties_serialization()
  981. {
  982. xlnt::workbook wb;
  983. auto ws = wb.active_sheet();
  984. ws.cell("A1").value("A1");
  985. ws.cell("A2").value("A2");
  986. ws.cell("B1").value("B1");
  987. ws.cell("B2").value("B2");
  988. xlnt_assert(!ws.has_active_cell());
  989. ws.active_cell("B1");
  990. xlnt_assert(ws.has_active_cell());
  991. xlnt_assert_equals(ws.active_cell(), "B1");
  992. wb.save("temp.xlsx");
  993. xlnt::workbook wb2;
  994. wb2.load("temp.xlsx");
  995. auto ws2 = wb2.active_sheet();
  996. xlnt_assert(ws2.has_active_cell());
  997. xlnt_assert_equals(ws2.active_cell(), "B1");
  998. }
  999. void test_clear_cell()
  1000. {
  1001. xlnt::workbook wb;
  1002. wb.load(path_helper::test_file("4_every_style.xlsx"));
  1003. auto ws = wb.active_sheet();
  1004. auto height = ws.calculate_dimension().height();
  1005. auto last_row = ws.highest_row();
  1006. xlnt_assert(ws.has_cell(xlnt::cell_reference(1, last_row)));
  1007. ws.clear_cell(xlnt::cell_reference(1, last_row));
  1008. xlnt_assert(!ws.has_cell(xlnt::cell_reference(1, last_row)));
  1009. xlnt_assert_equals(ws.highest_row(), last_row);
  1010. wb.save("temp.xlsx");
  1011. xlnt::workbook wb2;
  1012. wb2.load("temp.xlsx");
  1013. auto ws2 = wb2.active_sheet();
  1014. xlnt_assert_equals(ws2.calculate_dimension().height(), height);
  1015. xlnt_assert(!ws2.has_cell(xlnt::cell_reference(1, last_row)));
  1016. }
  1017. void test_clear_row()
  1018. {
  1019. xlnt::workbook wb;
  1020. wb.load(path_helper::test_file("4_every_style.xlsx"));
  1021. auto ws = wb.active_sheet();
  1022. auto height = ws.calculate_dimension().height();
  1023. auto last_row = ws.highest_row();
  1024. xlnt_assert(ws.has_cell(xlnt::cell_reference(1, last_row)));
  1025. ws.clear_row(last_row);
  1026. xlnt_assert(!ws.has_cell(xlnt::cell_reference(1, last_row)));
  1027. xlnt_assert_equals(ws.highest_row(), last_row - 1);
  1028. wb.save("temp.xlsx");
  1029. xlnt::workbook wb2;
  1030. wb2.load("temp.xlsx");
  1031. auto ws2 = wb2.active_sheet();
  1032. xlnt_assert_equals(ws2.calculate_dimension().height(), height - 1);
  1033. xlnt_assert(!ws2.has_cell(xlnt::cell_reference(1, last_row)));
  1034. }
  1035. void test_set_title()
  1036. {
  1037. xlnt::workbook wb;
  1038. auto ws1 = wb.active_sheet();
  1039. // empty titles are invalid
  1040. xlnt_assert_throws(ws1.title(""), xlnt::invalid_sheet_title);
  1041. // titles longer than 31 chars are invalid
  1042. std::string test_long_title(32, 'a');
  1043. xlnt_assert(test_long_title.size() > 31);
  1044. xlnt_assert_throws(ws1.title(test_long_title), xlnt::invalid_sheet_title);
  1045. // titles containing any of the following characters are invalid
  1046. std::string invalid_chars = "*:/\\?[]";
  1047. for (char &c : invalid_chars)
  1048. {
  1049. std::string invalid_char = std::string("Sheet") + c;
  1050. xlnt_assert_throws(ws1.title(invalid_char), xlnt::invalid_sheet_title);
  1051. }
  1052. // duplicate names are invalid
  1053. auto ws2 = wb.create_sheet();
  1054. xlnt_assert_throws(ws2.title(ws1.title()), xlnt::invalid_sheet_title);
  1055. xlnt_assert_throws(ws1.title(ws2.title()), xlnt::invalid_sheet_title);
  1056. // naming as self is valid and is ignored
  1057. auto ws1_title = ws1.title();
  1058. auto ws2_title = ws2.title();
  1059. xlnt_assert_throws_nothing(ws1.title(ws1.title()));
  1060. xlnt_assert_throws_nothing(ws2.title(ws2.title()));
  1061. xlnt_assert(ws1_title == ws1.title());
  1062. xlnt_assert(ws2_title == ws2.title());
  1063. }
  1064. void test_set_title_unicode()
  1065. {
  1066. xlnt::workbook wb;
  1067. auto ws = wb.active_sheet();
  1068. // the 31 char limit also applies to 4-byte characters
  1069. const std::string test_long_utf8_title("巧みな外交は戦争を避ける助けとなる。");
  1070. xlnt_assert_throws_nothing(ws.title(test_long_utf8_title));
  1071. const std::string invalid_unicode("\xe6\x97\xa5\xd1\x88\xfa");
  1072. xlnt_assert_throws(ws.title(invalid_unicode),
  1073. xlnt::exception);
  1074. }
  1075. void test_phonetics()
  1076. {
  1077. xlnt::workbook wb;
  1078. wb.load(path_helper::test_file("15_phonetics.xlsx"));
  1079. auto ws = wb.active_sheet();
  1080. xlnt_assert_equals(ws.cell("A1").phonetics_visible(), true);
  1081. xlnt_assert_equals(ws.cell("A1").value<xlnt::rich_text>().phonetic_runs()[0].text, "シュウ ");
  1082. xlnt_assert_equals(ws.cell("B1").phonetics_visible(), true);
  1083. xlnt_assert_equals(ws.cell("C1").phonetics_visible(), false);
  1084. wb.save("temp.xlsx");
  1085. xlnt::workbook wb2;
  1086. wb2.load("temp.xlsx");
  1087. auto ws2 = wb2.active_sheet();
  1088. xlnt_assert_equals(ws2.cell("A1").phonetics_visible(), true);
  1089. xlnt_assert_equals(ws2.cell("A1").value<xlnt::rich_text>().phonetic_runs()[0].text, "シュウ ");
  1090. xlnt_assert_equals(ws2.cell("B1").phonetics_visible(), true);
  1091. xlnt_assert_equals(ws2.cell("C1").phonetics_visible(), false);
  1092. }
  1093. void test_insert_rows()
  1094. {
  1095. xlnt::workbook wb;
  1096. auto ws = wb.active_sheet();
  1097. // set up a 2x2 grid
  1098. ws.cell("A1").value("A1");
  1099. ws.cell("A2").value("A2");
  1100. ws.cell("B1").value("B1");
  1101. ws.cell("B2").value("B2");
  1102. xlnt::row_properties row_prop;
  1103. row_prop.height = 1;
  1104. ws.add_row_properties(1, row_prop);
  1105. row_prop.height = 2;
  1106. ws.add_row_properties(2, row_prop);
  1107. xlnt::column_properties col_prop;
  1108. col_prop.width = 1;
  1109. ws.add_column_properties(1, col_prop);
  1110. col_prop.width = 2;
  1111. ws.add_column_properties(2, col_prop);
  1112. // insert
  1113. ws.insert_rows(2, 2);
  1114. // first row should be unchanged
  1115. xlnt_assert(ws.cell("A1").has_value());
  1116. xlnt_assert(ws.cell("B1").has_value());
  1117. xlnt_assert_equals(ws.cell("A1").value<std::string>(), "A1");
  1118. xlnt_assert_equals(ws.cell("B1").value<std::string>(), "B1");
  1119. xlnt_assert_equals(ws.row_properties(1).height, 1);
  1120. // second and third rows should be empty
  1121. xlnt_assert(!ws.cell("A2").has_value());
  1122. xlnt_assert(!ws.cell("B2").has_value());
  1123. xlnt_assert(!ws.has_row_properties(2));
  1124. xlnt_assert(!ws.cell("A3").has_value());
  1125. xlnt_assert(!ws.cell("B3").has_value());
  1126. xlnt_assert(!ws.has_row_properties(3));
  1127. // fourth row should have the contents and properties of the second
  1128. xlnt_assert(ws.cell("A4").has_value());
  1129. xlnt_assert(ws.cell("B4").has_value());
  1130. xlnt_assert_equals(ws.cell("A4").value<std::string>(), "A2");
  1131. xlnt_assert_equals(ws.cell("B4").value<std::string>(), "B2");
  1132. xlnt_assert_equals(ws.row_properties(4).height, 2);
  1133. // column properties should remain unchanged
  1134. xlnt_assert(ws.has_column_properties(1));
  1135. xlnt_assert(ws.has_column_properties(2));
  1136. }
  1137. void test_insert_columns()
  1138. {
  1139. xlnt::workbook wb;
  1140. auto ws = wb.active_sheet();
  1141. // set up a 2x2 grid
  1142. ws.cell("A1").value("A1");
  1143. ws.cell("A2").value("A2");
  1144. ws.cell("B1").value("B1");
  1145. ws.cell("B2").value("B2");
  1146. xlnt::row_properties row_prop;
  1147. row_prop.height = 1;
  1148. ws.add_row_properties(1, row_prop);
  1149. row_prop.height = 2;
  1150. ws.add_row_properties(2, row_prop);
  1151. xlnt::column_properties col_prop;
  1152. col_prop.width = 1;
  1153. ws.add_column_properties(1, col_prop);
  1154. col_prop.width = 2;
  1155. ws.add_column_properties(2, col_prop);
  1156. // insert
  1157. ws.insert_columns(2, 2);
  1158. // first column should be unchanged
  1159. xlnt_assert(ws.cell("A1").has_value());
  1160. xlnt_assert(ws.cell("A2").has_value());
  1161. xlnt_assert_equals(ws.cell("A1").value<std::string>(), "A1");
  1162. xlnt_assert_equals(ws.cell("A2").value<std::string>(), "A2");
  1163. xlnt_assert_equals(ws.column_properties(1).width, 1);
  1164. // second and third columns should be empty
  1165. xlnt_assert(!ws.cell("B1").has_value());
  1166. xlnt_assert(!ws.cell("B2").has_value());
  1167. xlnt_assert(!ws.has_column_properties(2));
  1168. xlnt_assert(!ws.cell("C1").has_value());
  1169. xlnt_assert(!ws.cell("C2").has_value());
  1170. xlnt_assert(!ws.has_column_properties(3));
  1171. // fourth column should have the contents and properties of the second
  1172. xlnt_assert(ws.cell("D1").has_value());
  1173. xlnt_assert(ws.cell("D2").has_value());
  1174. xlnt_assert_equals(ws.cell("D1").value<std::string>(), "B1");
  1175. xlnt_assert_equals(ws.cell("D2").value<std::string>(), "B2");
  1176. xlnt_assert_equals(ws.column_properties(4).width, 2);
  1177. // row properties should remain unchanged
  1178. xlnt_assert_equals(ws.row_properties(1).height, 1);
  1179. xlnt_assert_equals(ws.row_properties(2).height, 2);
  1180. }
  1181. void test_delete_rows()
  1182. {
  1183. xlnt::workbook wb;
  1184. auto ws = wb.active_sheet();
  1185. // set up a 4x4 grid
  1186. for (int i = 1; i <= 4; ++i)
  1187. {
  1188. for (int j = 1; j <= 4; ++j)
  1189. {
  1190. ws.cell(xlnt::cell_reference(i, j)).value(xlnt::cell_reference(i, j).to_string());
  1191. }
  1192. xlnt::row_properties row_prop;
  1193. row_prop.height = i;
  1194. ws.add_row_properties(i, row_prop);
  1195. xlnt::column_properties col_prop;
  1196. col_prop.width = i;
  1197. ws.add_column_properties(i, col_prop);
  1198. }
  1199. // delete
  1200. ws.delete_rows(2, 2);
  1201. // first row should remain unchanged
  1202. xlnt_assert_equals(ws.cell("A1").value<std::string>(), "A1");
  1203. xlnt_assert_equals(ws.cell("B1").value<std::string>(), "B1");
  1204. xlnt_assert_equals(ws.cell("C1").value<std::string>(), "C1");
  1205. xlnt_assert_equals(ws.cell("D1").value<std::string>(), "D1");
  1206. xlnt_assert(ws.has_row_properties(1));
  1207. xlnt_assert_equals(ws.row_properties(1).height, 1);
  1208. // second row should have the contents and properties of the fourth
  1209. xlnt_assert_equals(ws.cell("A2").value<std::string>(), "A4");
  1210. xlnt_assert_equals(ws.cell("B2").value<std::string>(), "B4");
  1211. xlnt_assert_equals(ws.cell("C2").value<std::string>(), "C4");
  1212. xlnt_assert_equals(ws.cell("D2").value<std::string>(), "D4");
  1213. xlnt_assert(ws.has_row_properties(2));
  1214. xlnt_assert_equals(ws.row_properties(2).height, 4);
  1215. // third and fourth rows should be empty
  1216. auto empty_range = ws.range("A3:D4");
  1217. for (auto empty_row : empty_range)
  1218. {
  1219. for (auto empty_cell : empty_row)
  1220. {
  1221. xlnt_assert(!empty_cell.has_value());
  1222. }
  1223. }
  1224. xlnt_assert(!ws.has_row_properties(3));
  1225. xlnt_assert(!ws.has_row_properties(4));
  1226. // column properties should remain unchanged
  1227. for (int i = 1; i <= 4; ++i)
  1228. {
  1229. xlnt_assert(ws.has_column_properties(i));
  1230. xlnt_assert_equals(ws.column_properties(i).width, i);
  1231. }
  1232. }
  1233. void test_delete_columns()
  1234. {
  1235. xlnt::workbook wb;
  1236. auto ws = wb.active_sheet();
  1237. // set up a 4x4 grid
  1238. for (int i = 1; i <= 4; ++i)
  1239. {
  1240. for (int j = 1; j <= 4; ++j)
  1241. {
  1242. ws.cell(xlnt::cell_reference(i, j)).value(xlnt::cell_reference(i, j).to_string());
  1243. }
  1244. xlnt::row_properties row_prop;
  1245. row_prop.height = i;
  1246. ws.add_row_properties(i, row_prop);
  1247. xlnt::column_properties col_prop;
  1248. col_prop.width = i;
  1249. ws.add_column_properties(i, col_prop);
  1250. }
  1251. // delete
  1252. ws.delete_columns(2, 2);
  1253. // first column should remain unchanged
  1254. xlnt_assert_equals(ws.cell("A1").value<std::string>(), "A1");
  1255. xlnt_assert_equals(ws.cell("A2").value<std::string>(), "A2");
  1256. xlnt_assert_equals(ws.cell("A3").value<std::string>(), "A3");
  1257. xlnt_assert_equals(ws.cell("A4").value<std::string>(), "A4");
  1258. xlnt_assert(ws.has_column_properties("A"));
  1259. xlnt_assert_equals(ws.column_properties("A").width.get(), 1);
  1260. // second column should have the contents and properties of the fourth
  1261. xlnt_assert_equals(ws.cell("B1").value<std::string>(), "D1");
  1262. xlnt_assert_equals(ws.cell("B2").value<std::string>(), "D2");
  1263. xlnt_assert_equals(ws.cell("B3").value<std::string>(), "D3");
  1264. xlnt_assert_equals(ws.cell("B4").value<std::string>(), "D4");
  1265. xlnt_assert(ws.has_column_properties("B"));
  1266. xlnt_assert_equals(ws.column_properties("B").width.get(), 4);
  1267. // third and fourth columns should be empty
  1268. auto empty_range = ws.range("C1:D4");
  1269. for (auto empty_row : empty_range)
  1270. {
  1271. for (auto empty_cell : empty_row)
  1272. {
  1273. xlnt_assert(!empty_cell.has_value());
  1274. }
  1275. }
  1276. xlnt_assert(!ws.has_column_properties("C"));
  1277. xlnt_assert(!ws.has_column_properties("D"));
  1278. // row properties should remain unchanged
  1279. for (int i = 1; i <= 4; ++i)
  1280. {
  1281. xlnt_assert(ws.has_row_properties(i));
  1282. xlnt_assert_equals(ws.row_properties(i).height, i);
  1283. }
  1284. }
  1285. void test_insert_too_many()
  1286. {
  1287. xlnt::workbook wb;
  1288. auto ws = wb.active_sheet();
  1289. xlnt_assert_throws(ws.insert_rows(10, 4294967290),
  1290. xlnt::exception);
  1291. }
  1292. void test_insert_delete_moves_merges()
  1293. {
  1294. xlnt::workbook wb;
  1295. auto ws = wb.active_sheet();
  1296. ws.merge_cells("A1:A2");
  1297. ws.merge_cells("B2:B3");
  1298. ws.merge_cells("C3:C4");
  1299. ws.merge_cells("A5:B5");
  1300. ws.merge_cells("B6:C6");
  1301. ws.merge_cells("C7:D7");
  1302. {
  1303. ws.insert_rows(3, 3);
  1304. ws.insert_columns(3, 3);
  1305. auto merged = ws.merged_ranges();
  1306. std::vector<xlnt::range_reference> expected =
  1307. {
  1308. xlnt::range_reference { "A1:A2" }, // stays
  1309. xlnt::range_reference { "B2:B6" }, // expands
  1310. xlnt::range_reference { "F6:F7" }, // shifts
  1311. xlnt::range_reference { "A8:B8" }, // stays (shifted down)
  1312. xlnt::range_reference { "B9:F9" }, // expands (shifted down)
  1313. xlnt::range_reference { "F10:G10" }, // shifts (shifted down)
  1314. };
  1315. xlnt_assert_equals(merged, expected);
  1316. }
  1317. {
  1318. ws.delete_rows(4, 2);
  1319. ws.delete_columns(4, 2);
  1320. auto merged = ws.merged_ranges();
  1321. std::vector<xlnt::range_reference> expected =
  1322. {
  1323. xlnt::range_reference { "A1:A2" }, // stays
  1324. xlnt::range_reference { "B2:B4" }, // expands
  1325. xlnt::range_reference { "D4:D5" }, // shifts
  1326. xlnt::range_reference { "A6:B6" }, // stays (shifted down)
  1327. xlnt::range_reference { "B7:D7" }, // expands (shifted down)
  1328. xlnt::range_reference { "D8:E8" }, // shifts (shifted down)
  1329. };
  1330. xlnt_assert_equals(merged, expected);
  1331. }
  1332. }
  1333. void test_hidden_sheet()
  1334. {
  1335. xlnt::workbook wb;
  1336. wb.load(path_helper::test_file("16_hidden_sheet.xlsx"));
  1337. xlnt_assert_equals(wb.sheet_hidden_by_index(1), true);
  1338. }
  1339. void test_xlsm_read_write()
  1340. {
  1341. {
  1342. xlnt::workbook wb;
  1343. wb.load(path_helper::test_file("17_xlsm.xlsm"));
  1344. auto ws = wb.sheet_by_title("Sheet1");
  1345. auto rows = ws.rows();
  1346. xlnt_assert_equals(rows[0][0].value<std::string>(), "Values");
  1347. xlnt_assert_equals(rows[1][0].value<int>(), 100);
  1348. xlnt_assert_equals(rows[2][0].value<int>(), 200);
  1349. xlnt_assert_equals(rows[3][0].value<int>(), 300);
  1350. xlnt_assert_equals(rows[4][0].value<int>(), 400);
  1351. xlnt_assert_equals(rows[5][0].value<int>(), 500);
  1352. xlnt_assert_equals(rows[0][1].value<std::string>(), "Sum");
  1353. xlnt_assert_equals(rows[1][1].formula(), "SumVBA(A2:A6)");
  1354. xlnt_assert_equals(rows[1][1].value<int>(), 1500);
  1355. // change sheet value
  1356. ws.cell("A6").value(1000);
  1357. wb.save("17_xlsm_modified.xlsm");
  1358. }
  1359. {
  1360. xlnt::workbook wb;
  1361. wb.load("17_xlsm_modified.xlsm");
  1362. auto ws = wb.sheet_by_title("Sheet1");
  1363. auto rows = ws.rows();
  1364. xlnt_assert_equals(rows[0][0].value<std::string>(), "Values");
  1365. xlnt_assert_equals(rows[1][0].value<int>(), 100);
  1366. xlnt_assert_equals(rows[2][0].value<int>(), 200);
  1367. xlnt_assert_equals(rows[3][0].value<int>(), 300);
  1368. xlnt_assert_equals(rows[4][0].value<int>(), 400);
  1369. // sheet value changed (500 -> 1000)
  1370. xlnt_assert_equals(rows[5][0].value<int>(), 1000);
  1371. xlnt_assert_equals(rows[0][1].value<std::string>(), "Sum");
  1372. xlnt_assert_equals(rows[1][1].formula(), "SumVBA(A2:A6)");
  1373. // formula value not changed (we can't execute vba)
  1374. xlnt_assert_equals(rows[1][1].value<int>(), 1500);
  1375. }
  1376. }
  1377. void test_issue_484()
  1378. {
  1379. // Include first empty rows/columns in column dimensions
  1380. // if skip_null is false.
  1381. xlnt::workbook wb;
  1382. auto ws = wb.active_sheet();
  1383. ws.cell("B12").value("AAA");
  1384. xlnt_assert_equals("B12:B12", ws.rows(true).reference());
  1385. xlnt_assert_equals("A1:B12", ws.rows(false).reference());
  1386. xlnt_assert_equals("B12:B12", ws.columns(true).reference());
  1387. xlnt_assert_equals("A1:B12", ws.columns(false).reference());
  1388. }
  1389. };
  1390. static worksheet_test_suite x;