1 // Copyright (c) 2014-2020 Thomas Fussell
2 // Copyright (c) 2010-2015 openpyxl
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, WRISING 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 <memory>
28 #include <string>
29 #include <unordered_map>
30 
31 #include <xlnt/xlnt_config.hpp>
32 #include <xlnt/cell/cell_type.hpp>
33 #include <xlnt/cell/index_types.hpp>
34 #include <xlnt/cell/rich_text.hpp>
35 
36 namespace xlnt {
37 
38 enum class calendar;
39 
40 class alignment;
41 class base_format;
42 class border;
43 class cell_reference;
44 class comment;
45 class fill;
46 class font;
47 class format;
48 class number_format;
49 class protection;
50 class range;
51 class relationship;
52 class style;
53 class workbook;
54 class worksheet;
55 class xlsx_consumer;
56 class xlsx_producer;
57 class phonetic_pr;
58 
59 struct date;
60 struct datetime;
61 struct time;
62 struct timedelta;
63 
64 namespace detail {
65 
66 class xlsx_consumer;
67 class xlsx_producer;
68 
69 struct cell_impl;
70 
71 } // namespace detail
72 
73 /// <summary>
74 /// Describes a unit of data in a worksheet at a specific coordinate and its
75 /// associated properties.
76 /// </summary>
77 /// <remarks>
78 /// Properties of interest include style, type, value, and address.
79 /// The Cell class is required to know its value and type, display options,
80 /// and any other features of an Excel cell.Utilities for referencing
81 /// cells using Excel's 'A1' column/row nomenclature are also provided.
82 /// </remarks>
83 class XLNT_API cell
84 {
85 public:
86     /// <summary>
87     /// Alias xlnt::cell_type to xlnt::cell::type since it looks nicer.
88     /// </summary>
89     using type = cell_type;
90 
91     /// <summary>
92     /// Returns a map of error strings such as \#DIV/0! and their associated indices.
93     /// </summary>
94     static const std::unordered_map<std::string, int> &error_codes();
95 
96     /// <summary>
97     /// Default copy constructor.
98     /// </summary>
99     cell(const cell &) = default;
100 
101     // value
102 
103     /// <summary>
104     /// Returns true if value has been set and has not been cleared using cell::clear_value().
105     /// </summary>
106     bool has_value() const;
107 
108     /// <summary>
109     /// Returns the value of this cell as an instance of type T.
110     /// Overloads exist for most C++ fundamental types like bool, int, etc. as well
111     /// as for std::string and xlnt datetime types: date, time, datetime, and timedelta.
112     /// </summary>
113     template <typename T>
114     T value() const;
115 
116     /// <summary>
117     /// Makes this cell have a value of type null.
118     /// All other cell attributes are retained.
119     /// </summary>
120     void clear_value();
121 
122     /// <summary>
123     /// Sets the type of this cell to null.
124     /// </summary>
125     void value(std::nullptr_t);
126 
127     /// <summary>
128     /// Sets the value of this cell to the given boolean value.
129     /// </summary>
130     void value(bool boolean_value);
131 
132     /// <summary>
133     /// Sets the value of this cell to the given value.
134     /// </summary>
135     void value(int int_value);
136 
137     /// <summary>
138     /// Sets the value of this cell to the given value.
139     /// </summary>
140     void value(unsigned int int_value);
141 
142     /// <summary>
143     /// Sets the value of this cell to the given value.
144     /// </summary>
145     void value(long long int int_value);
146 
147     /// <summary>
148     /// Sets the value of this cell to the given value.
149     /// </summary>
150     void value(unsigned long long int int_value);
151 
152     /// <summary>
153     /// Sets the value of this cell to the given value.
154     /// </summary>
155     void value(float float_value);
156 
157     /// <summary>
158     /// Sets the value of this cell to the given value.
159     /// </summary>
160     void value(double float_value);
161 
162     /// <summary>
163     /// Sets the value of this cell to the given value.
164     /// </summary>
165     void value(const date &date_value);
166 
167     /// <summary>
168     /// Sets the value of this cell to the given value.
169     /// </summary>
170     void value(const time &time_value);
171 
172     /// <summary>
173     /// Sets the value of this cell to the given value.
174     /// </summary>
175     void value(const datetime &datetime_value);
176 
177     /// <summary>
178     /// Sets the value of this cell to the given value.
179     /// </summary>
180     void value(const timedelta &timedelta_value);
181 
182     /// <summary>
183     /// Sets the value of this cell to the given value.
184     /// </summary>
185     void value(const std::string &string_value);
186 
187     /// <summary>
188     /// Sets the value of this cell to the given value.
189     /// </summary>
190     void value(const char *string_value);
191 
192     /// <summary>
193     /// Sets the value of this cell to the given value.
194     /// </summary>
195     void value(const rich_text &text_value);
196 
197     /// <summary>
198     /// Sets the value and formatting of this cell to that of other_cell.
199     /// </summary>
200     void value(const cell other_cell);
201 
202     /// <summary>
203     /// Analyzes string_value to determine its type, convert it to that type,
204     /// and set the value of this cell to that converted value.
205     /// </summary>
206     void value(const std::string &string_value, bool infer_type);
207 
208     /// <summary>
209     /// Returns the type of this cell.
210     /// </summary>
211     type data_type() const;
212 
213     /// <summary>
214     /// Sets the type of this cell. This should usually be done indirectly
215     /// by setting the value of the cell to a value of that type.
216     /// </summary>
217     void data_type(type t);
218 
219     // properties
220 
221     /// <summary>
222     /// There's no reason to keep a cell which has no value and is not a placeholder.
223     /// Returns true if this cell has no value, style, isn't merged, etc.
224     /// </summary>
225     bool garbage_collectible() const;
226 
227     /// <summary>
228     /// Returns true iff this cell's number format matches a date format.
229     /// </summary>
230     bool is_date() const;
231 
232     // position
233 
234     /// <summary>
235     /// Returns a cell_reference that points to the location of this cell.
236     /// </summary>
237     cell_reference reference() const;
238 
239     /// <summary>
240     /// Returns the column of this cell.
241     /// </summary>
242     column_t column() const;
243 
244     /// <summary>
245     /// Returns the numeric index (A == 1) of the column of this cell.
246     /// </summary>
247     column_t::index_t column_index() const;
248 
249     /// <summary>
250     /// Returns the row of this cell.
251     /// </summary>
252     row_t row() const;
253 
254     /// <summary>
255     /// Returns the location of this cell as an ordered pair (left, top).
256     /// </summary>
257     std::pair<int, int> anchor() const;
258 
259     // hyperlink
260 
261     /// <summary>
262     /// Returns the relationship of this cell's hyperlink.
263     /// </summary>
264     class hyperlink hyperlink() const;
265 
266     /// <summary>
267     /// Adds a hyperlink to this cell pointing to the URI of the given value and sets
268     /// the text value of the cell to the given parameter.
269     /// </summary>
270     void hyperlink(const std::string &url, const std::string &display = "");
271 
272     /// <summary>
273     /// Adds an internal hyperlink to this cell pointing to the given cell.
274     /// </summary>
275     void hyperlink(xlnt::cell target, const std::string &display = "");
276 
277     /// <summary>
278     /// Adds an internal hyperlink to this cell pointing to the given range.
279     /// </summary>
280     void hyperlink(xlnt::range target, const std::string &display = "");
281 
282     /// <summary>
283     /// Returns true if this cell has a hyperlink set.
284     /// </summary>
285     bool has_hyperlink() const;
286 
287     // computed formatting
288 
289     /// <summary>
290     /// Returns the alignment that should be used when displaying this cell
291     /// graphically based on the workbook default, the cell-level format,
292     /// and the named style applied to the cell in that order.
293     /// </summary>
294     class alignment computed_alignment() const;
295 
296     /// <summary>
297     /// Returns the border that should be used when displaying this cell
298     /// graphically based on the workbook default, the cell-level format,
299     /// and the named style applied to the cell in that order.
300     /// </summary>
301     class border computed_border() const;
302 
303     /// <summary>
304     /// Returns the fill that should be used when displaying this cell
305     /// graphically based on the workbook default, the cell-level format,
306     /// and the named style applied to the cell in that order.
307     /// </summary>
308     class fill computed_fill() const;
309 
310     /// <summary>
311     /// Returns the font that should be used when displaying this cell
312     /// graphically based on the workbook default, the cell-level format,
313     /// and the named style applied to the cell in that order.
314     /// </summary>
315     class font computed_font() const;
316 
317     /// <summary>
318     /// Returns the number format that should be used when displaying this cell
319     /// graphically based on the workbook default, the cell-level format,
320     /// and the named style applied to the cell in that order.
321     /// </summary>
322     class number_format computed_number_format() const;
323 
324     /// <summary>
325     /// Returns the protection that should be used when displaying this cell
326     /// graphically based on the workbook default, the cell-level format,
327     /// and the named style applied to the cell in that order.
328     /// </summary>
329     class protection computed_protection() const;
330 
331     // format
332 
333     /// <summary>
334     /// Returns true if this cell has had a format applied to it.
335     /// </summary>
336     bool has_format() const;
337 
338     /// <summary>
339     /// Returns the format applied to this cell. If this cell has no
340     /// format, an invalid_attribute exception will be thrown.
341     /// </summary>
342     const class format format() const;
343 
344     /// <summary>
345     /// Applies the cell-level formatting of new_format to this cell.
346     /// </summary>
347     void format(const class format new_format);
348 
349     /// <summary>
350     /// Removes the cell-level formatting from this cell.
351     /// This doesn't affect the style that may also be applied to the cell.
352     /// Throws an invalid_attribute exception if no format is applied.
353     /// </summary>
354     void clear_format();
355 
356     /// <summary>
357     /// Returns the number format of this cell.
358     /// </summary>
359     class number_format number_format() const;
360 
361     /// <summary>
362     /// Creates a new format in the workbook, sets its number_format
363     /// to the given format, and applies the format to this cell.
364     /// </summary>
365     void number_format(const class number_format &format);
366 
367     /// <summary>
368     /// Returns the font applied to the text in this cell.
369     /// </summary>
370     class font font() const;
371 
372     /// <summary>
373     /// Creates a new format in the workbook, sets its font
374     /// to the given font, and applies the format to this cell.
375     /// </summary>
376     void font(const class font &font_);
377 
378     /// <summary>
379     /// Returns the fill applied to this cell.
380     /// </summary>
381     class fill fill() const;
382 
383     /// <summary>
384     /// Creates a new format in the workbook, sets its fill
385     /// to the given fill, and applies the format to this cell.
386     /// </summary>
387     void fill(const class fill &fill_);
388 
389     /// <summary>
390     /// Returns the border of this cell.
391     /// </summary>
392     class border border() const;
393 
394     /// <summary>
395     /// Creates a new format in the workbook, sets its border
396     /// to the given border, and applies the format to this cell.
397     /// </summary>
398     void border(const class border &border_);
399 
400     /// <summary>
401     /// Returns the alignment of the text in this cell.
402     /// </summary>
403     class alignment alignment() const;
404 
405     /// <summary>
406     /// Creates a new format in the workbook, sets its alignment
407     /// to the given alignment, and applies the format to this cell.
408     /// </summary>
409     void alignment(const class alignment &alignment_);
410 
411     /// <summary>
412     /// Returns the protection of this cell.
413     /// </summary>
414     class protection protection() const;
415 
416     /// <summary>
417     /// Creates a new format in the workbook, sets its protection
418     /// to the given protection, and applies the format to this cell.
419     /// </summary>
420     void protection(const class protection &protection_);
421 
422     // style
423 
424     /// <summary>
425     /// Returns true if this cell has had a style applied to it.
426     /// </summary>
427     bool has_style() const;
428 
429     /// <summary>
430     /// Returns a wrapper pointing to the named style applied to this cell.
431     /// </summary>
432     class style style();
433 
434     /// <summary>
435     /// Returns a wrapper pointing to the named style applied to this cell.
436     /// </summary>
437     const class style style() const;
438 
439     /// <summary>
440     /// Sets the named style applied to this cell to a style named style_name.
441     /// Equivalent to style(new_style.name()).
442     /// </summary>
443     void style(const class style &new_style);
444 
445     /// <summary>
446     /// Sets the named style applied to this cell to a style named style_name.
447     /// If this style has not been previously created in the workbook, a
448     /// key_not_found exception will be thrown.
449     /// </summary>
450     void style(const std::string &style_name);
451 
452     /// <summary>
453     /// Removes the named style from this cell.
454     /// An invalid_attribute exception will be thrown if this cell has no style.
455     /// This will not affect the cell format of the cell.
456     /// </summary>
457     void clear_style();
458 
459     // formula
460 
461     /// <summary>
462     /// Returns the string representation of the formula applied to this cell.
463     /// </summary>
464     std::string formula() const;
465 
466     /// <summary>
467     /// Sets the formula of this cell to the given value.
468     /// This formula string should begin with '='.
469     /// </summary>
470     void formula(const std::string &formula);
471 
472     /// <summary>
473     /// Removes the formula from this cell. After this is called, has_formula() will return false.
474     /// </summary>
475     void clear_formula();
476 
477     /// <summary>
478     /// Returns true if this cell has had a formula applied to it.
479     /// </summary>
480     bool has_formula() const;
481 
482     // printing
483 
484     /// <summary>
485     /// Returns a string representing the value of this cell. If the data type is not a string,
486     /// it will be converted according to the number format.
487     /// </summary>
488     std::string to_string() const;
489 
490     // merging
491 
492     /// <summary>
493     /// Returns true iff this cell has been merged with one or more
494     /// surrounding cells.
495     /// </summary>
496     bool is_merged() const;
497 
498     /// <summary>
499     /// Makes this a merged cell iff merged is true.
500     /// Generally, this shouldn't be called directly. Instead,
501     /// use worksheet::merge_cells on its parent worksheet.
502     /// </summary>
503     void merged(bool merged);
504 
505     // phonetics
506 
507     /// <summary>
508     /// Returns true if this cell is set to show phonetic information.
509     /// </summary>
510     bool phonetics_visible() const;
511 
512     /// <summary>
513     /// Enables the display of phonetic information on this cell.
514     /// </summary>
515     void show_phonetics(bool phonetics);
516 
517     /// <summary>
518     /// Returns the error string that is stored in this cell.
519     /// </summary>
520     std::string error() const;
521 
522     /// <summary>
523     /// Directly assigns the value of this cell to be the given error.
524     /// </summary>
525     void error(const std::string &error);
526 
527     /// <summary>
528     /// Returns a cell from this cell's parent workbook at
529     /// a relative offset given by the parameters.
530     /// </summary>
531     cell offset(int column, int row);
532 
533     /// <summary>
534     /// Returns the worksheet that owns this cell.
535     /// </summary>
536     class worksheet worksheet();
537 
538     /// <summary>
539     /// Returns the worksheet that owns this cell.
540     /// </summary>
541     const class worksheet worksheet() const;
542 
543     /// <summary>
544     /// Returns the workbook of the worksheet that owns this cell.
545     /// </summary>
546     class workbook &workbook();
547 
548     /// <summary>
549     /// Returns the workbook of the worksheet that owns this cell.
550     /// </summary>
551     const class workbook &workbook() const;
552 
553     /// <summary>
554     /// Returns the base date of the parent workbook.
555     /// </summary>
556     calendar base_date() const;
557 
558     /// <summary>
559     /// Returns to_check after verifying and fixing encoding, size, and illegal characters.
560     /// </summary>
561     std::string check_string(const std::string &to_check);
562 
563     // comment
564 
565     /// <summary>
566     /// Returns true if this cell has a comment applied.
567     /// </summary>
568     bool has_comment();
569 
570     /// <summary>
571     /// Deletes the comment applied to this cell if it exists.
572     /// </summary>
573     void clear_comment();
574 
575     /// <summary>
576     /// Gets the comment applied to this cell.
577     /// </summary>
578     class comment comment();
579 
580     /// <summary>
581     /// Creates a new comment with the given text and optional author and
582     /// applies it to the cell.
583     /// </summary>
584     void comment(const std::string &text,
585         const std::string &author = "Microsoft Office User");
586 
587     /// <summary>
588     /// Creates a new comment with the given text, formatting, and optional
589     /// author and applies it to the cell.
590     /// </summary>
591     void comment(const std::string &comment_text,
592         const class font &comment_font,
593         const std::string &author = "Microsoft Office User");
594 
595     /// <summary>
596     /// Apply the comment provided as the only argument to the cell.
597     /// </summary>
598     void comment(const class comment &new_comment);
599 
600     /// <summary>
601     /// Returns the width of this cell in pixels.
602     /// </summary>
603     double width() const;
604 
605     /// <summary>
606     /// Returns the height of this cell in pixels.
607     /// </summary>
608     double height() const;
609 
610     // operators
611 
612     /// <summary>
613     /// Makes this cell interally point to rhs.
614     /// The cell data originally pointed to by this cell will be unchanged.
615     /// </summary>
616     cell &operator=(const cell &rhs);
617 
618     /// <summary>
619     /// Returns true if this cell the same cell as comparand (compared by reference).
620     /// </summary>
621     bool operator==(const cell &comparand) const;
622 
623     /// <summary>
624     /// Returns false if this cell the same cell as comparand (compared by reference).
625     /// </summary>
626     bool operator!=(const cell &comparand) const;
627 
628 private:
629     friend class style;
630     friend class worksheet;
631     friend class detail::xlsx_consumer;
632     friend class detail::xlsx_producer;
633     friend struct detail::cell_impl;
634 
635     /// <summary>
636     /// Returns a non-const reference to the format of this cell.
637     /// This is for internal use only.
638     /// </summary>
639     class format modifiable_format();
640 
641     /// <summary>
642     /// Delete the default zero-argument constructor.
643     /// </summary>
644     cell() = delete;
645 
646     /// <summary>
647     /// Private constructor to create a cell from its implementation.
648     /// </summary>
649     cell(detail::cell_impl *d);
650 
651     /// <summary>
652     /// A pointer to this cell's implementation.
653     /// </summary>
654     detail::cell_impl *d_;
655 };
656 
657 /// <summary>
658 /// Returns true if this cell is uninitialized.
659 /// </summary>
660 XLNT_API bool operator==(std::nullptr_t, const cell &cell);
661 
662 /// <summary>
663 /// Returns true if this cell is uninitialized.
664 /// </summary>
665 XLNT_API bool operator==(const cell &cell, std::nullptr_t);
666 
667 /// <summary>
668 /// Convenience function for writing cell to an ostream.
669 /// Uses cell::to_string() internally.
670 /// </summary>
671 XLNT_API std::ostream &operator<<(std::ostream &stream, const xlnt::cell &cell);
672 
673 template <>
674 bool cell::value<bool>() const;
675 
676 template <>
677 int cell::value<int>() const;
678 
679 template <>
680 unsigned int cell::value<unsigned int>() const;
681 
682 template <>
683 long long int cell::value<long long int>() const;
684 
685 template <>
686 unsigned long long cell::value<unsigned long long int>() const;
687 
688 template <>
689 float cell::value<float>() const;
690 
691 template <>
692 double cell::value<double>() const;
693 
694 template <>
695 date cell::value<date>() const;
696 
697 template <>
698 time cell::value<time>() const;
699 
700 template <>
701 datetime cell::value<datetime>() const;
702 
703 template <>
704 timedelta cell::value<timedelta>() const;
705 
706 template <>
707 std::string cell::value<std::string>() const;
708 
709 template <>
710 rich_text cell::value<rich_text>() const;
711 
712 } // namespace xlnt
713