Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failed to convert to std::vector<std::string]> #213

Open
xrui94 opened this issue Apr 13, 2023 · 2 comments
Open

Failed to convert to std::vector<std::string]> #213

xrui94 opened this issue Apr 13, 2023 · 2 comments

Comments

@xrui94
Copy link

xrui94 commented Apr 13, 2023

124 lines of code:

auto rv = std::vector<std::string>(worksheet.row(2).values());

Reading the first row of data was successful, but an error was reported when reading the second row of data. I think all data should be able to be converted into string, but my program is not working.
image

image

@xrui94 xrui94 changed the title Failed conversion to std::vector<[int, double, bool, std::string]> Failed convert to std::vector<std::string]> Apr 13, 2023
@xrui94 xrui94 changed the title Failed convert to std::vector<std::string]> Failed to convert to std::vector<std::string]> Apr 13, 2023
@troldal
Copy link
Owner

troldal commented Apr 13, 2023

The .values() function from the XLRow class does not return a std::vector of strings, but XLCellValue objects. An XLCellValue object can be implicitly converted to a the type corresponding to the value type of the cell. That is the reason that your program can read the first row (all values are strings), but the following lines are mixed types.

I suggest that you use the following code instead:

auto rv = std::vector<XLCellValue>(worksheet.row(2).values());

For each element in the std::vector, you can then use the .get<>() function to get the underlying data. To check which data type is contained in the XLCellValue object, use the .type() member function.

@xrui94
Copy link
Author

xrui94 commented Apr 17, 2023

Yes, I got it. This is my code bellow, but I think it is not the best solution.

std::string GetValue(const OpenXLSX::XLCellValue& value)
{
    switch (value.type())
    {
    case OpenXLSX::XLValueType::Empty:
        return "";
    case OpenXLSX::XLValueType::Boolean:
       return std::to_string(value.get<bool>());
    case OpenXLSX::XLValueType::Integer:
        return std::to_string(value.get<int32_t>());
    case OpenXLSX::XLValueType::Float:
        return std::to_string(value.get<double>());
    case OpenXLSX::XLValueType::Error:
       return "";
    case OpenXLSX::XLValueType::String:
        return value.get<std::string>();
    default:
        return "";
    }
}

// ... (A function, but some code has been omitted here)

   uint32_t startRow = 2;
   uint32_t endRow = worksheet.rowCount();
   for (const OpenXLSX::XLRow &row : worksheet.rows(startRow, endRow))
   {
       DotField dotField;
       //auto rowValues = std::vector<std::string>(row.values());    // 对于小数,会报错
       auto rowValues = std::vector<OpenXLSX::XLCellValue>(row.values());

       for (const std::pair<std::string, uint16_t> &item : fieldLoc)
       {
           //
           auto value = GetValue(rowValues[item.second - 1]);
           if (item.first == "id")
           {
               if (value.size() == 0) break; // ID不能为空,因此,遇到空行,则跳过该行
               dotField.id = value;
           }
           else if (item.first == "x")
               dotField.x = std::stof(value);
           else if (item.first == "y")
               dotField.y = std::stof(value);
           else if (item.first == "height")
               dotField.height = std::stof(value);
           else
               std::cerr << "Failed read valur for \"" << item.first << "\" field." << std::endl;
       }

       // ID不能为空,因此,遇到空行,则跳过该行
       if (dotField.id.size() == 0) continue;

       // 保存当前读取的一行数据
       //data.insert({ dotField.id, dotField });
       data[dotField.id] = dotField;
   }

// ... (A function, but some code has been omitted here)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants