Files
GostGenerator/controller/csvexporter.cpp
T
2026-09-02 12:48:03 +03:00

172 lines
5.5 KiB
C++

#include "csvexporter.h"
#include "../model/specificationpcbtablemodel.h"
#include "../model/specificationtablemodel.h"
#include "../model/perechentablemodel.h"
#include "../model/vedomosttablemodel.h"
#include "../model/simplelisttablemodel.h"
#include <QFile>
#include <QTextStream>
#include <QTextCodec>
#include <QDebug>
#include <QStandardPaths>
CSVExporter::CSVExporter(QObject *parent)
: QObject(parent)
{
}
bool CSVExporter::exportSpecificationPCB(const QString &filePath, SpecificationPCBTableModel *model)
{
if (!model) {
m_lastError = "Модель таблицы не указана";
return false;
}
return exportTableModel(filePath, model, true);
}
bool CSVExporter::exportSpecification(const QString &filePath, SpecificationTableModel *model)
{
if (!model) {
m_lastError = "Модель таблицы не указана";
return false;
}
return exportTableModel(filePath, model, true);
}
bool CSVExporter::exportPerechen(const QString &filePath, PerechenTableModel *model)
{
if (!model) {
m_lastError = "Модель таблицы не указана";
return false;
}
return exportTableModel(filePath, model, true);
}
bool CSVExporter::exportVedomost(const QString &filePath, VedomostTableModel *model)
{
if (!model) {
m_lastError = "Модель таблицы не указана";
return false;
}
return exportTableModel(filePath, model, true);
}
bool CSVExporter::exportSimpleList(const QString &filePath, SimpleListTableModel *model)
{
if (!model) {
m_lastError = "Модель таблицы не указана";
return false;
}
return exportTableModel(filePath, model, true);
}
bool CSVExporter::exportTableModel(const QString &filePath, QAbstractTableModel *model, bool includeHeaders)
{
if (!model) {
m_lastError = "Модель таблицы не указана";
return false;
}
QFile file(filePath);
if (!file.open(QIODevice::WriteOnly)) {
m_lastError = QString("Не удалось открыть файл для записи: %1").arg(file.errorString());
return false;
}
// Записываем UTF-8 BOM напрямую в файл для корректного отображения в Excel
QByteArray bom;
bom.append(static_cast<char>(0xEF));
bom.append(static_cast<char>(0xBB));
bom.append(static_cast<char>(0xBF));
if (file.write(bom) != 3) {
m_lastError = "Не удалось записать BOM в файл";
file.close();
return false;
}
QTextStream out(&file);
// Устанавливаем кодировку UTF-8 для корректного отображения в Excel
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
if (codec) {
out.setCodec(codec);
} else {
// Fallback на строковое имя кодировки
out.setCodec("UTF-8");
}
// Отключаем автоматическое определение Unicode, так как мы уже записали BOM
out.setAutoDetectUnicode(false);
// Разделитель для CSV (точка с запятой для Excel в русской локали)
const QString delimiter = ";";
try {
// Записываем заголовки, если нужно
if (includeHeaders) {
QStringList headers;
int columnCount = model->columnCount();
for (int col = 0; col < columnCount; ++col) {
QVariant header = model->headerData(col, Qt::Horizontal, Qt::DisplayRole);
headers << escapeCsvValue(header.toString());
}
out << formatCsvRow(headers) << "\n";
}
// Записываем данные
int rowCount = model->rowCount();
for (int row = 0; row < rowCount; ++row) {
QStringList values;
int columnCount = model->columnCount();
for (int col = 0; col < columnCount; ++col) {
QModelIndex index = model->index(row, col);
QVariant data = model->data(index, Qt::DisplayRole);
values << escapeCsvValue(data.toString());
}
out << formatCsvRow(values) << "\n";
}
file.close();
m_lastError.clear();
return true;
} catch (const std::exception &e) {
m_lastError = QString("Ошибка при записи в файл: %1").arg(e.what());
file.close();
return false;
} catch (...) {
m_lastError = "Неизвестная ошибка при записи в файл";
file.close();
return false;
}
}
QString CSVExporter::escapeCsvValue(const QString &value) const
{
// Если значение содержит разделитель, кавычки или перенос строки, заключаем в кавычки
if (value.contains(";") || value.contains("\"") || value.contains("\n") || value.contains("\r")) {
// Экранируем кавычки удвоением
QString escaped = value;
escaped.replace("\"", "\"\"");
return "\"" + escaped + "\"";
}
return value;
}
QString CSVExporter::formatCsvRow(const QStringList &values) const
{
return values.join(";");
}
QString CSVExporter::lastError() const
{
return m_lastError;
}