Evgenii Legotckoi
25 ноября 2015 г. 20:43

QML - Урок 017. Экспорт данных в формат CSV из модели данных в QML Qt

В том случае, если Вам понадобилось выгрузить таблицу с данными из приложения в файл формата CSV , интерфейс которого ещё и написан на QML , то спешу с этой статьей, чтобы дать небольшую подсказку.

Например, в статье по работе с базой данных SQLite в приложении на QML была создана база данных, в которую добавлялись данные и удалялись из неё. При этом они отображались в TableView , который был уже частью интерфейса, написанного на QML. А для отображения этой таблицы использовалась модель данных, наследованная от QSqlQueryModel .

Предлагаю воспользоваться исходниками того проекта и расширить его так, чтобы в приложении имелась кнопочка для экспорта данных в файл формата CSV .

Что такое формат CSV

CSV (от англ. Comma-Separated Values — значения, разделённые запятыми) — текстовый формат, предназначенный для представления табличных данных. Каждая строка файла — это одна строка таблицы. Значения отдельных колонок разделяются разделительным символом (delimiter) — запятой (

,
). Однако, большинство программ вольно трактует стандарт CSV и допускают использование иных символов в качестве разделителя.

Вообще суть работы сведётся к тому, чтобы сделать метод в нашей модели данных, который будет дергать данные из этой модели и разделять точкой с запятой каждую ячейку в строке, а каждую строку разделять символом новой строки "\n".


Пишем метод для экспорта таблицы в файл формата CSV

В заголовочный файл нашего проекта добавим соответственно новый метод для экспорта и ещё один метод, который будет возвращать количество строк в модели данных. Метод для экспорта данных объявим как СЛОТ , чтобы он был доступен из QML слоя.

private:
    int countRow();

public slots:
    void exportCSV();

Здесь я оговорюсь в том плане, для чего же нужен собственный метод, который возвращает количество строк, если QSqlQueryModel, от которого Мы наследовались имеет собственный метод, который возвращает количество строк. Проблема в том, что он работает не так, как нам надо. Если строк меньше 256, то всё работает нормально, а если больше, то он всё равно будет возвращать значение 256 или в некоторых случаях 512. В общем реальных данных не дождётесь. Поэтому проблема решается SQL-запросом к базе данных.

int ListModel::countRow()
{
    QSqlQuery query;
    query.prepare("SELECT COUNT(*) FROM " TABLE " ;");
    query.exec();
    query.first();

    return query.value(0).toInt();
}

А теперь разберём метод для экспорта данных в файл CSV, в котором будет участвовать выше приведённый метод получения числа строк в таблице.

void ListModel::exportCSV()
{
    /* Создаём объекта файла CSV и указываем путь к этому файлу
     * Не забудьте указать валидный путь и расширение .csv
     * */
    QFile csvFile("C:/example/excelExample.csv");

    // Открываем, или создаём файл, если он не существует
    if(csvFile.open( QIODevice::WriteOnly ))
    {
        // Создаём текстовый поток, в который будем писать данные
        QTextStream textStream( &csvFile );
        QStringList stringList; // Вспомогательный объект QSqtringList, который сформирует строку

        // Проходимся по всем строкам ...
        for( int row = 0; row < this->countRow(); row++ )
        {
            stringList.clear(); // ... каждый раз очищая stringList
            /* Если обратить внимание в заголовочный файл, то
             * можно увидеть в перечислении Roles, что ролей модели всего 4
             * */
            for( int column = 0; column < 4; column++ )
            {
                // Записываем в stringList каждый элемент таблицы
                stringList << this->data(this->index(row, column), Qt::UserRole + 1 + column).toString();
            }
            /* После чего отправляем весь stringList в файл через текстовый поток
             * добавляя разделители в виде ";", а также поставив в конце символ окончания строки
             * */
            textStream << stringList.join( ';' )+"\n";
        }
        // Закрываем файл - готово
        csvFile.close();
    }
}

main.qml

Ну а для того, чтобы это дело можно было запустить, добавлю в rowLayout в файле main.qml кнопочку, по нажатию которой будем запускать экспорт данных из таблицы в файл CSV.

// Программный код из предыдущего урока    
    // Слой с TaxtField`ами и Button для занесения записей в базу данных
    RowLayout {
        id: rowLayout

    // Программный код из предыдущего урока

        // Кнопочка для запуска экспорта в Excel
        Button {
            text: qsTr("Экспорт в Excel")

            // Запускаем экспорт
            onClicked: {
                myModel.exportCSV()
            }
        }
    }

Итог

В результате обновлённый код приложения из прошлой статьи позволит Вам сохранить данные из таблицы в файл CSV. А как это будет работать, смотрите в видеоуроке.

Видеоурок

Вам это нравится? Поделитесь в социальных сетях!

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
  • Последние комментарии
  • Evgenii Legotckoi
    16 апреля 2025 г. 17:08
    Благодарю за отзыв. И вам желаю всяческих успехов!
  • IscanderChe
    12 апреля 2025 г. 17:12
    Добрый день. Спасибо Вам за этот проект и отдельно за ответы на форуме, которые мне очень помогли в некоммерческих пет-проектах. Профессиональным программистом я так и не стал, но узнал мно…
  • AK
    1 апреля 2025 г. 11:41
    Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
  • Evgenii Legotckoi
    9 марта 2025 г. 21:02
    К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
  • VP
    9 марта 2025 г. 16:14
    Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…