172 lines
5.5 KiB
C++
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;
|
|
}
|
|
|