Wt examples  4.10.4
CsvUtil.C
Go to the documentation of this file.
1 #include <fstream>
2 
3 #include <boost/tokenizer.hpp>
4 
5 #include <Wt/WAbstractItemModel.h>
6 #include <Wt/WStandardItemModel.h>
7 #include <Wt/WStandardItem.h>
8 #include <Wt/WString.h>
9 
10 #include "CsvUtil.h"
11 
12 /*
13  * A standard item which converts text edits to numbers
14  */
15 class NumericItem : public WStandardItem {
16 public:
17  virtual std::unique_ptr<WStandardItem> clone() const {
18  return std::unique_ptr<NumericItem>(std::make_unique<NumericItem>());
19  }
20 
21  virtual void setData(const cpp17::any &data, ItemDataRole role = ItemDataRole::User) {
22  cpp17::any dt;
23 
24  if (role == ItemDataRole::Edit) {
25  std::string s = asString(data).toUTF8();
26 
27  char *end;
28  double d = std::strtod(s.c_str(), &end);
29  if (*end == 0)
30  dt = cpp17::any(d);
31  else
32  dt = data;
33  } else
34  dt = data;
35 
36  WStandardItem::setData(dt, role);
37  }
38 };
39 
40 std::shared_ptr<WStandardItemModel> csvToModel(const std::string& csvFile,
41  bool firstLineIsHeaders)
42 {
43  std::ifstream f(csvFile.c_str());
44 
45  if (f) {
46  std::shared_ptr<WStandardItemModel> result = std::make_shared<WStandardItemModel>(0, 0);
47  result->setItemPrototype(std::make_unique<NumericItem>());
48  readFromCsv(f, result, -1, firstLineIsHeaders);
49  return result;
50  } else
51  return nullptr;
52 }
53 
54 void readFromCsv(std::istream& f, std::shared_ptr<WAbstractItemModel> model,
55  int numRows, bool firstLineIsHeaders)
56 {
57  int csvRow = 0;
58 
59  while (f) {
60  std::string line;
61  getline(f, line);
62 
63  if (f) {
64  typedef boost::tokenizer<boost::escaped_list_separator<char> >
65  CsvTokenizer;
66  CsvTokenizer tok(line);
67 
68  int col = 0;
69  for (CsvTokenizer::iterator i = tok.begin();
70  i != tok.end(); ++i, ++col) {
71 
72  if (col >= model->columnCount())
73  model->insertColumns(model->columnCount(),
74  col + 1 - model->columnCount());
75 
76  if (firstLineIsHeaders && csvRow == 0)
77  model->setHeaderData(col, cpp17::any{WString{*i}});
78  else {
79  int dataRow = firstLineIsHeaders ? csvRow - 1 : csvRow;
80 
81  if (numRows != -1 && dataRow >= numRows)
82  return;
83 
84  if (dataRow >= model->rowCount())
85  model->insertRows(model->rowCount(),
86  dataRow + 1 - model->rowCount());
87 
88  cpp17::any data{WString{*i}};
89  model->setData(dataRow, col, data);
90  }
91  }
92  }
93 
94  ++csvRow;
95  }
96 }
virtual std::unique_ptr< WStandardItem > clone() const
Definition: CsvUtil.C:17
virtual void setData(const cpp17::any &data, ItemDataRole role=ItemDataRole::User)
Definition: CsvUtil.C:21
virtual void setData(const cpp17::any &data, ItemDataRole role=ItemDataRole::User)
virtual cpp17::any data(ItemDataRole role=ItemDataRole::User) const
std::string toUTF8() const
WString asString(const cpp17::any &v, const WString &formatString=WString())
std::shared_ptr< WStandardItemModel > csvToModel(const std::string &csvFile, bool firstLineIsHeaders)
Definition: CsvUtil.C:40
void readFromCsv(std::istream &f, std::shared_ptr< WAbstractItemModel > model, int numRows, bool firstLineIsHeaders)
Definition: CsvUtil.C:54