QT C++ All datas shown on same column when export csv?
Asked Answered
P

1

1

I want to save a set of data in csv file. I have no problem with registration. My problem is in the form of saving. All data are collected in column A. I have 2 graphs in total, graph1 and graph2. Graph1 should be in column A and Graph2 should be in column B. How can I set this up.

Here is code for export csv

void MainWindow::exportArraysToCSV(QStringList labelList, QList < QList < double >> dataColums, QChar sep) {
  QString filters("CSV files (*.csv);;All files (*.*)");
  QString defaultFilter("CSVi files (*.csv)");
  QString fileName = QFileDialog::getSaveFileName(0, "Save file", QCoreApplication::applicationDirPath(),
    filters, & defaultFilter);
  QFile file(fileName);

  if (file.open(QFile::WriteOnly | QFile::Append)) {
    QTextStream data( & file);
    QStringList strList;

    foreach(auto label, labelList) {
      if (label.length() > 0)
        strList.append("\"" + label + "\"");
      else
        strList.append("");
    }

    data << strList.join(",") << "\n";

    int maxRowCount = 0;
    foreach(auto column, dataColums)
    maxRowCount = qMax(maxRowCount, column.count());

    for (int i = 5; i < maxRowCount; ++i) // rows
    {
      strList.clear();
      for (int j = 0; j < 2; ++j) // columns
      {
        if (i < dataColums[j].count())
          strList.append(QString::number(dataColums[j][i], 'f'));


        else
          strList.append("\"\" ");
      }

      data << strList.join(";") + "\n";


    }
    file.close();
  }
}

I think this code for join all data on same column. How can I split it?

 data << strList.join(",") << "\n";

Here is write log to csv function

void Logger::writeLogCSV(QStringList labelList, QList<double> dataList, bool addTime)
{
    QTextStream out(logFile);

    if (addTime)
    {
        if (csvLabelsBuffer.contains("time") == false)
            csvLabelsBuffer.insert(0, "time");
    }

    if (labelList.count() == 0)
    {
        qDebug() << "Empty label list - abort csv write";
        return;
    }

    bool canAddLabel = false;
    for (auto i = 2; i < labelList.count(); ++i)
    {
        if (csvLabelsBuffer.count() == 2 || csvLabelsBuffer.contains(labelList[i]) == false)
        {
            canAddLabel = true;
            csvLabelsBuffer.append(labelList[i]);
        }
    }

    if (canAddLabel)
    {
        canAddLabel = false;

        QStringList origFile = out.readAll().split(QRegExp("[\r\n]"), QString::SplitBehavior::SkipEmptyParts);

        for (auto i = 2; i < csvLabelsBuffer.count(); ++i)
            out << "\"" + csvLabelsBuffer[i] + "\t";
        out << "";
       // out << "\n";

        if (origFile.length() > 0)
        {
            while (origFile.first().contains("\""))
                origFile.removeFirst();
        }

        logFile->resize(0); // delete contents !

        for (auto i = 2; i < origFile.count(); ++i) // Start from second line (data without first line which contains labels)
            out << origFile[i] + ",";

        return;
    }

    // add Data !
    for (auto i = 2; i < csvLabelsBuffer.count(); ++i)
    {
        out.atEnd(); // ???

        int index = labelList.indexOf(csvLabelsBuffer[i]); 
        if (index >= 0 && index < dataList.count())
            out << QString::number(dataList[index], 'f') + ",";
        else if (csvLabelsBuffer[i] == "time")
            out << QDateTime::currentDateTimeUtc().toString("yyyy-MM-ddTHH:MM:ss.zzzZ") + ',';
    }

    out << "\n \n";

}

Here is csv file. I need move graph2 and all datas to column B

Praetorian answered 28/7, 2022 at 15:19 Comment(19)
Your question is a little hard to follow for me.Trilobite
Sorry, I forgot add picture of csv file. I'm editing questionPraetorian
Cannot reproduce (after clearing it a bit to actually make "reproducible"). With sample data QList<QList<double>> dataColums({{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}}); your code prints 1-5 in the first column, and 6-10 in the second column (iterating from 0 of course, not from 5).Izzo
But what you are showing in the picture is just how Excel opens your file, probably nothing to do with the correct/incorrect file content (which looks OK, values are comma-separated). Dunno why, maybe some locale config. Anyway for excel you can also open a blank document and use "data import" feature where you can specify data formatting.Izzo
I need to assign the ones after the comma to B graph1 and the ones after the comma should stay in A graph2 and the ones after the comma should stay in B.Praetorian
I see that. What does the csv look like that is produced by this code. Do you wrongly have quotes in your csv such that it looks like "Graph1, Graph2" in the csv? Excel will honor the quotes and put it in a single column between double quotes.Trilobite
I read something that the use of strList.join(",") is to collect all the data in one place. I'm wondering if this could be my problem and I don't know how to get rid of joinen.Praetorian
I'm wondering if this could be my problem I don't think that is the problem. I think quotes are the problem. It would be helpful to see a part of the csv as text and not a picture of excel.Trilobite
You may want to put a breakpoint on this line: data << strList.join(",") << "\n"; and see what the contents of strList is. If at that line the strList contains only 1 item your bug is above this code.Trilobite
@Trilobite I tried but csv is samePraetorian
You will have to debug. I don't think the problem is in the code that you show.Trilobite
I updated question can you check please. @TrilobitePraetorian
I Will debug. I hope can solve it. what you mean provide a portion of the csv file as text?Praetorian
You show the output in excel. It would be helpful if you opened the csv file in any text editor and copied and pasted the first 3 lines of text. That would show if the problem is the quotation marks. Seeing the output in Excel we have to guess why Excel is displaying it the way it is instead of looking at the produced csv.Trilobite
It is a lot of code to go through. Can you write a minimal reproducible example?Unsuitable
As you said, I opened it in different ways, but the result was the same. I got the code from answer 2 of the question here. linkPraetorian
you should open the generated file with a text editor and post some lines of it here to your answer. By Opening the File with excel you need to set the seperator it will use to split the the row into columns. Usually it will use ',' but sometimes it will default to ';'Dugas
I tried this and worked perfect with comma. But when I save a new csv I need open it and split again. How can I do this automaticaly?Praetorian
in your code there are 2 places where the seperator ist set as ";"Dugas
D
1

you should open the generated file with a text editor and post some lines of it here to your answer. By Opening the File with excel you need to set the seperator it will use to split the the row into columns. Usually it will use ',' but sometimes it will default to ';'.

this will seperate them by comma, which is the standard for csv:

void MainWindow::exportArraysToCSV(QStringList labelList, QList < QList < double >> dataColums, QChar sep) {
      QString filters("CSV files (*.csv);;All files (*.*)");
      QString defaultFilter("CSVi files (*.csv)");
      QString fileName = QFileDialog::getSaveFileName(0, "Save file", QCoreApplication::applicationDirPath(),
        filters, & defaultFilter);
      QFile file(fileName);
    
      if (file.open(QFile::WriteOnly | QFile::Append)) {
        QTextStream data( & file);
        QStringList strList;
    
        foreach(auto label, labelList) {
          if (label.length() > 0)
            strList.append("\"" + label + "\"");
          else
            strList.append("");
        }
    
        data << strList.join(",") << "\n";
    
        int maxRowCount = 0;
        foreach(auto column, dataColums)
        maxRowCount = qMax(maxRowCount, column.count());
    
        for (int i = 5; i < maxRowCount; ++i) // rows
        {
          strList.clear();
          for (int j = 0; j < 2; ++j) // columns
          {
            if (i < dataColums[j].count())
              strList.append(QString::number(dataColums[j][i], 'f'));
    
    
            else
              strList.append("\"\" ");
          }
    
          data << strList.join(",") + "\n";
    
    
        }
        file.close();
      }
    }

If that does not fix your problem, then you need to open your csv with a texteditor and see whats wrong with it. Post some lines of it here then.

Dugas answered 2/8, 2022 at 13:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.