xlsxcell.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. // xlsxcell.cpp
  2. #include <cmath>
  3. #include <QtGlobal>
  4. #include <QDebug>
  5. #include <QDateTime>
  6. #include <QDate>
  7. #include <QTime>
  8. #include "xlsxcell.h"
  9. #include "xlsxcell_p.h"
  10. #include "xlsxformat.h"
  11. #include "xlsxformat_p.h"
  12. #include "xlsxutility_p.h"
  13. #include "xlsxworksheet.h"
  14. #include "xlsxworkbook.h"
  15. QT_BEGIN_NAMESPACE_XLSX
  16. CellPrivate::CellPrivate(Cell *p) :
  17. q_ptr(p)
  18. {
  19. }
  20. CellPrivate::CellPrivate(const CellPrivate * const cp)
  21. : parent(cp->parent)
  22. , cellType(cp->cellType)
  23. , value(cp->value)
  24. , formula(cp->formula)
  25. , format(cp->format)
  26. , richString(cp->richString)
  27. , styleNumber(cp->styleNumber)
  28. {
  29. }
  30. /*!
  31. \class Cell
  32. \inmodule QtXlsx
  33. \brief The Cell class provides a API that is used to handle the worksheet cell.
  34. */
  35. /*!
  36. \enum Cell::CellType
  37. \value BooleanType Boolean type
  38. \value NumberType Number type, can be blank or used with forumula
  39. \value ErrorType Error type
  40. \value SharedStringType Shared string type
  41. \value StringType String type, can be used with forumula
  42. \value InlineStringType Inline string type
  43. */
  44. /*!
  45. * \internal
  46. * Created by Worksheet only.
  47. */
  48. // qint32 styleIndex = (-1)
  49. Cell::Cell(const QVariant &data,
  50. CellType type,
  51. const Format &format,
  52. Worksheet *parent,
  53. qint32 styleIndex ) :
  54. d_ptr(new CellPrivate(this))
  55. {
  56. d_ptr->value = data;
  57. d_ptr->cellType = type;
  58. d_ptr->format = format;
  59. d_ptr->parent = parent;
  60. d_ptr->styleNumber = styleIndex;
  61. }
  62. /*!
  63. * \internal
  64. */
  65. Cell::Cell(const Cell * const cell):
  66. d_ptr(new CellPrivate(cell->d_ptr))
  67. {
  68. d_ptr->q_ptr = this;
  69. }
  70. /*!
  71. * Destroys the Cell and cleans up.
  72. */
  73. Cell::~Cell()
  74. {
  75. if ( NULL != d_ptr )
  76. delete d_ptr;
  77. }
  78. /*!
  79. * Return the dataType of this Cell
  80. */
  81. Cell::CellType Cell::cellType() const
  82. {
  83. Q_D(const Cell);
  84. return d->cellType;
  85. }
  86. /*!
  87. * Return the data content of this Cell
  88. */
  89. QVariant Cell::value() const
  90. {
  91. Q_D(const Cell);
  92. return d->value;
  93. }
  94. /*!
  95. * Return the data content of this Cell for reading
  96. */
  97. QVariant Cell::readValue() const
  98. {
  99. Q_D(const Cell);
  100. QVariant ret; // return value
  101. ret = d->value;
  102. Format fmt = this->format();
  103. if (isDateTime())
  104. {
  105. QVariant vDT = dateTime();
  106. if ( vDT.isNull() )
  107. {
  108. return QVariant();
  109. }
  110. // https://github.com/QtExcel/QXlsx/issues/171
  111. // https://www.qt.io/blog/whats-new-in-qmetatype-qvariant
  112. #if QT_VERSION >= 0x060000 // Qt 6.0 or over
  113. if ( vDT.metaType().id() == QMetaType::QDateTime )
  114. {
  115. ret = vDT;
  116. }
  117. else if ( vDT.metaType().id() == QMetaType::QDate )
  118. {
  119. ret = vDT;
  120. }
  121. else if ( vDT.metaType().id() == QMetaType::QTime )
  122. {
  123. ret = vDT;
  124. }
  125. else
  126. {
  127. return QVariant();
  128. }
  129. #else
  130. if ( vDT.type() == QVariant::DateTime )
  131. {
  132. ret = vDT;
  133. }
  134. else if ( vDT.type() == QVariant::Date )
  135. {
  136. ret = vDT;
  137. }
  138. else if ( vDT.type() == QVariant::Time )
  139. {
  140. ret = vDT;
  141. }
  142. else
  143. {
  144. return QVariant();
  145. }
  146. #endif
  147. // QDateTime dt = dateTime();
  148. // ret = dt;
  149. // QString strFormat = fmt.numberFormat();
  150. // if (!strFormat.isEmpty())
  151. // {
  152. // // TODO: use number format
  153. // }
  154. // qint32 styleNo = d->styleNumber;
  155. // if (styleNo == 10)
  156. // {
  157. // }
  158. // if (styleNo == 11)
  159. // {
  160. // QTime timeValue = dt.time(); // only time. (HH:mm:ss)
  161. // ret = timeValue;
  162. // return ret;
  163. // }
  164. // if (styleNo == 12)
  165. // {
  166. // }
  167. // if (styleNo == 13) // (HH:mm:ss)
  168. // {
  169. // double dValue = d->value.toDouble();
  170. // int day = int(dValue); // unit is day.
  171. // double deciamlPointValue1 = dValue - double(day);
  172. // double dHour = deciamlPointValue1 * (double(1.0) / double(24.0));
  173. // int hour = int(dHour);
  174. // double deciamlPointValue2 = deciamlPointValue1 - (double(hour) * (double(1.0) / double(24.0)));
  175. // double dMin = deciamlPointValue2 * (double(1.0) / double(60.0));
  176. // int min = int(dMin);
  177. // double deciamlPointValue3 = deciamlPointValue2 - (double(min) * (double(1.0) / double(60.0)));
  178. // double dSec = deciamlPointValue3 * (double(1.0) / double(60.0));
  179. // int sec = int(dSec);
  180. // int totalHour = hour + (day * 24);
  181. // QString strTime;
  182. // strTime = QString("%1:%2:%3").arg(totalHour).arg(min).arg(sec);
  183. // ret = strTime;
  184. // return ret;
  185. // }
  186. // return ret;
  187. // */
  188. }
  189. if (hasFormula())
  190. {
  191. QString formulaString = this->formula().formulaText();
  192. ret = formulaString;
  193. return ret; // return formula string
  194. }
  195. return ret;
  196. }
  197. /*!
  198. * Return the style used by this Cell. If no style used, 0 will be returned.
  199. */
  200. Format Cell::format() const
  201. {
  202. Q_D(const Cell);
  203. return d->format;
  204. }
  205. /*!
  206. * Returns true if the cell has one formula.
  207. */
  208. bool Cell::hasFormula() const
  209. {
  210. Q_D(const Cell);
  211. return d->formula.isValid();
  212. }
  213. /*!
  214. * Return the formula contents if the dataType is Formula
  215. */
  216. CellFormula Cell::formula() const
  217. {
  218. Q_D(const Cell);
  219. return d->formula;
  220. }
  221. /*!
  222. * Returns whether the value is probably a dateTime or not
  223. */
  224. bool Cell::isDateTime() const
  225. {
  226. Q_D(const Cell);
  227. Cell::CellType cellType = d->cellType;
  228. double dValue = d->value.toDouble(); // number
  229. // QString strValue = d->value.toString().toUtf8();
  230. bool isValidFormat = d->format.isValid();
  231. bool isDateTimeFormat = d->format.isDateTimeFormat(); // datetime format
  232. // dev67
  233. if ( cellType == NumberType ||
  234. cellType == DateType ||
  235. cellType == CustomType )
  236. {
  237. if ( dValue >= 0 &&
  238. isValidFormat &&
  239. isDateTimeFormat )
  240. {
  241. return true;
  242. }
  243. }
  244. return false;
  245. }
  246. /*!
  247. * Return the data time value.
  248. */
  249. /*
  250. QDateTime Cell::dateTime() const
  251. {
  252. Q_D(const Cell);
  253. if (!isDateTime())
  254. return QDateTime();
  255. return datetimeFromNumber(d->value.toDouble(), d->parent->workbook()->isDate1904());
  256. }
  257. */
  258. QVariant Cell::dateTime() const
  259. {
  260. Q_D(const Cell);
  261. if (!isDateTime())
  262. {
  263. return QVariant();
  264. }
  265. // dev57
  266. QVariant ret;
  267. double dValue = d->value.toDouble();
  268. bool isDate1904 = d->parent->workbook()->isDate1904();
  269. ret = datetimeFromNumber(dValue, isDate1904);
  270. return ret;
  271. }
  272. /*!
  273. * Returns whether the cell is probably a rich string or not
  274. */
  275. bool Cell::isRichString() const
  276. {
  277. Q_D(const Cell);
  278. if ( d->cellType != SharedStringType &&
  279. d->cellType != InlineStringType &&
  280. d->cellType != StringType )
  281. {
  282. return false;
  283. }
  284. return d->richString.isRichString();
  285. }
  286. qint32 Cell::styleNumber() const
  287. {
  288. Q_D(const Cell);
  289. qint32 ret = d->styleNumber;
  290. return ret;
  291. }
  292. QT_END_NAMESPACE_XLSX