VS2019+Qt 实现xml和excel互相转换
需求
1.将所有的excel内容读取出来并写入到xml中
2.将xml文件读取出来并将内容写入到excel中
使用到的模块
第三方库 QXlsx
QXmlStreamReader/QXmlStreamWriter
QFile
关于QXlsx
QXlsx是一个封装好的第三方库,里面封装了对excel文件的操作方法,使用起来相比Qt自带的简化了很多操作。
Qxlsx Github地址
常用操作
bool write(int row, int col, const QVariant &value, const Format &format = Format()) 常用于在对应的excel格子中写内容。
QVariant read(int row, int col) const 常用于读取对应格子的内容,返回的是QVariant类型,需要自己转成对应的类型。
bool insertImage(int row, int col, const QImage &image) 在对应格子插入图片。
QStringList sheetNames() const 获取excel中所有的工作表。
bool selectSheet(const QString &name) 切换工作表。
bool deleteSheet(const QString &name) 删除工作表。
bool save() const
bool saveAs(const QString &xlsXname) const保存excel。
Excel->XML代码演示
// 创建xlsx对象 用R标识为读取
QXlsx::Document xlsxR(filePath);
QFileInfo fileInfo(filePath);
auto exportFilePath = QString("%1/%2_%3.xml").arg(fileInfo.path()).arg(fileInfo.baseName()).arg(language.at(languageGroup.checkedId()));;
QFile file(exportFilePath);
if(!file.open(QIODevice::WriteOnly|QIODevice::Text))
{
qDebug() << QString("Open file %1 failed.").arg(exportFilePath);
return;
}
// 创建xml写入对象 并设置自动格式化
QXmlStreamWriter writer(&file);
writer.setAutoFormatting(true);
writer.writeStartDocument(); // 写入开始<?xml version="1.0" encoding="UTF-8"?>
// 开始遍历excel
for (QString sheetName : xlsxR.sheetNames())
{
if (!xlsxR.selectSheet(sheetName))
{
qDebug() << QString("select Sheet %1 failed").arg(sheetName);
return;
}
writer.writeStartElement(xlsxR.read(2, 1).toString());
writer.writeAttribute("name", xlsxR.read(2, 1).toString());
writer.writeAttribute("text", xlsxR.read(2, col).toString());
writer.writeEndElement();
//do otherting
......
......
......
}
// 记得有始有终
writer.writeEndDocument();
file.close(); //关闭文件
XML->Excel代码演示
if(path == "")
{
return;
}
QFileInfo fileInfo(path);
auto fileName = fileInfo.baseName();
QFile file(path);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
qDebug() << "Open file " + fileInfo.fileName() + "failed.";
return;
}
m_excelPath = QString("%1/%2.xlsx").arg(fileInfo.path()).arg(fileBaseName[0]);
// 在此处判断excel是否存在 若存在则实例化时带上该路径,可以实现追加写入
若不存在则不带该路径,实现创建(覆盖)写入
if(QFile::exists(m_excelPath))
{
QXlsx::Document xlsxW(m_excelPath);
loadXMLToExcel(&xlsxW, true, file);
}
else
{
QXlsx::Document xlsxW;
loadXMLToExcel(&xlsxW, false, file);
}
file.close();
loadXMLToExcel(QXlsx::Document* xlsxW, bool isExist, QFile& file)
{
QXmlStreamReader xmlStreamReader(&file);
// 创建excel的字体,用于写入时,统一格式
QXlsx::Format format;
format.setFontSize(11);
format.setFont(QFont(QString::fromLocal8Bit("等线"), 11));
while (!xmlStreamReader.atEnd())
{
xmlStreamReader.readNext();
// 如果是xml的头节点 且 是自己需要的内容,则开始写入 (这里请自行判断)
if (xmlStreamReader.isStartElement())
{
// do something like this
xlsxW->write(row, 1, name, format);
}
}
}
// 当文件存在时 调用的是save() 不带路径保存
// 当文件不存在时,调用saveAs(path) 创建一个新的excel保存刚刚写入的东西
if (isExist)
{
if (xlsxW->save())
{
QMessageBox::information(this, "Save Excel", "Save Excel Succeed.");
}
}
else
{
if (xlsxW->saveAs(m_excelPath))
{
QMessageBox::information(this, "Save Excel", "Save Excel Succeed.");
}
}
总结
以上便是XML<->Excel互相转化的方法,由于XML和Excel的内容不尽相同,所以该部分代码仅作演示案例。
QXlsx的GitHub中给了一些参考方法,但是我觉得太麻烦了就没有用官方给的例子来做。
主要需要关注的点在于Excel想要追加写入应该怎么做 在代码演示中我也有给出方案。
欢迎各位大佬指正。