一、效果展示
实现Qt导出word文档,用户可选择保存位置、保存文件名。并设置word文档页边距、横向、分栏等属性。
点击导出
二、代码实现
在点击导出按钮槽函数中,获取每个Tablewidget中数据保存在有三个成员变量(type、name、argument)的结构体tempdata中,将结构体依次添加进QVector容器中。使用QVector保存各表格中数据是为了作为信号参数发送给子线程,子线程将数据导出为word,不影响主线程中的ui操作。将耗时操作交给小弟。
使用QFileDialog::getSaveFileName弹出选择保存对话框,并接收返回的保存文件名。如果文件名不为空,发送线程开始信号给Mainwindow,发送带有数据的信号以及带有文件名的信号给子线程,所有对象都是在Mainwindow中实例化,所以信号与槽在Mainwindow中连接。
void CalibrationReport::on_pushButton_clicked()//导出按钮槽函数
{
QVector<Reportstruct> data;
Reportstruct tempdata;
//传感器型号
tempdata.type = "传感器类型";
QTableWidgetItem *item = ui->tableWidget->item(0, 0);
tempdata.name = item->text();
QTableWidgetItem *item1 = ui->tableWidget->item(0, 1);
tempdata.argument = item1->text();
data.append(tempdata);
tempdata.type = "传感器类型";
QTableWidgetItem *item2 = ui->tableWidget->item(0, 2);
tempdata.name = item2->text();
QTableWidgetItem *item3 = ui->tableWidget->item(0, 3);
tempdata.argument = item3->text();
data.append(tempdata);
//特性参数
for (int row = 0; row < ui->tableWidget_2->rowCount(); ++row) {
Reportstruct tempdata;
QTableWidgetItem *typeItem = ui->tableWidget_2->item(row, 0);
QTableWidgetItem *nameItem = ui->tableWidget_2->item(row, 1);
if (typeItem && nameItem) {
tempdata.type = "特性参数";
tempdata.name = typeItem->text();
tempdata.argument = nameItem->text();
data.append(tempdata);
}
}
//环境
for (int row = 0; row < ui->tableWidget_3->rowCount(); ++row) {
Reportstruct tempdata;
QTableWidgetItem *typeItem = ui->tableWidget_3->item(row, 0);
QTableWidgetItem *nameItem = ui->tableWidget_3->item(row, 1);
if (typeItem && nameItem) {
tempdata.type = "环境";
tempdata.name = typeItem->text();
tempdata.argument = nameItem->text();
data.append(tempdata);
}
}
//电参数
for (int row = 0; row < ui->tableWidget_4->rowCount(); ++row) {
Reportstruct tempdata;
QTableWidgetItem *typeItem = ui->tableWidget_4->item(row, 0);
QTableWidgetItem *nameItem = ui->tableWidget_4->item(row, 1);
if (typeItem && nameItem) {
tempdata.type = "电参数";
tempdata.name = typeItem->text();
tempdata.argument = nameItem->text();
data.append(tempdata);
}
}
//结构
for (int row = 0; row < ui->tableWidget_5->rowCount(); ++row) {
Reportstruct tempdata;
QTableWidgetItem *typeItem = ui->tableWidget_5->item(row, 0);
QTableWidgetItem *nameItem = ui->tableWidget_5->item(row, 1);
if (typeItem && nameItem) {
tempdata.type = "结构";
tempdata.name = typeItem->text();
tempdata.argument = nameItem->text();
data.append(tempdata);
}
}
//使用说明
tempdata.type = "使用说明";
tempdata.name = "";
tempdata.argument = ui->textEdit->toPlainText();
data.append(tempdata);
tempdata.type = "时间";
tempdata.name = "";
tempdata.argument = ui->textEdit_5->toPlainText();
data.append(tempdata);
QString filename = QFileDialog::getSaveFileName(this, tr("Save to Word"), "", tr("Word Files (*.docx)"));
if(!filename.isEmpty())
{
send_filename(filename);
send_thread_data(data);
send_thread_start();
}
}
在子线程中创建word文档,设置页边距与横向显示,设为三栏模式,添加标题,需要换栏写入时先插入分栏符换栏。插入照片并设置大小与位置坐标,保存并退出发送子线程结束信号。
//创建word应用添加文档
QAxObject word("Word.Application");
word.setProperty("Visible", false);
QAxObject* documents = word.querySubObject("Documents");
QAxObject* document = documents->querySubObject("Add()");
//设置页面为横向与页边距
QAxObject* pageSetup = document->querySubObject("PageSetup");
pageSetup->setProperty("EqualColumn", true); // 设置为等宽列
pageSetup->setProperty("Orientation", 1); // 1表示横向,0表示纵向
pageSetup->setProperty("TopMargin", 1.27* 28.35);
pageSetup->setProperty("BottomMargin", 1.0* 28.35);
pageSetup->setProperty("LeftMargin", 1.27* 28.35);
pageSetup->setProperty("RightMargin", 1.27* 28.35);
//设置word三栏模式
QAxObject* sections = document->querySubObject("Sections");
QAxObject* section = sections->querySubObject("Item(int)", 1);
QAxObject* page_setup = section->querySubObject("PageSetup");
QAxObject* text_columns = page_setup->querySubObject("TextColumns");
text_columns->dynamicCall("SetCount(int)", 3);
//标题
QAxObject* range = document->querySubObject("Content");
range->dynamicCall("InsertAfter(QString)", "传感器校验报告");
QAxObject* font = range->querySubObject("Font");
font->setProperty("Name", "等线");
font->setProperty("Size", 18);
font->setProperty("Bold", true);
range->dynamicCall("InsertParagraphAfter()");
......
//环境
//插入分栏符换栏写入
QAxObject *selection = word.querySubObject("Selection");
selection->dynamicCall("EndKey(int)", 6);
selection->dynamicCall("InsertBreak(int)", 8);
QAxObject *range3 = range->querySubObject("Duplicate");
range3->dynamicCall("Collapse(int)", 0);
range3->dynamicCall("InsertAfter(QString)", "环境");
range3->dynamicCall("InsertParagraphAfter()");
QAxObject* font3 = range3->querySubObject("Font");
font3->setProperty("Name", "等线");
font3->setProperty("Size", 10.5);
font3->setProperty("Bold", true);
......
//设置公司图标照片
//lisi_filepath是图片绝对路径
if(!lisi_filepath.isEmpty())
{
QAxObject *shapes2 = document->querySubObject("Shapes");
QAxObject *shape2 = shapes2->querySubObject("AddPicture(const QString&)", lisi_filepath);
shape2->setProperty("Width", 80);
shape2->setProperty("Height", 40);
shape2->setProperty("Left", 650);
shape2->setProperty("Top", 475);
}
//保存关闭退出
document->dynamicCall("SaveAs(const QString&)", savefilename);
document->dynamicCall("Close()");
word.dynamicCall("Quit()");
end_thread();//线程结束信号