main.cpp
PdfReportGenerator pdfReportGenerator;
// 加载中文字体
if (QFontDatabase::addApplicationFont(":/new/prefix1/simsun.ttf") == -1) {
QMessageBox::warning(nullptr, "警告", "无法加载中文字体");
}
// 解析日志文件
QVector<LogEntry> entries;
if (!pdfReportGenerator.parseLogFile("1.txt", entries)) {
QMessageBox::critical(nullptr, "错误", "无法打开日志文件");
return ;
}
// 生成PDF表格
pdfReportGenerator.createPdfWithTable(entries);
QMessageBox::information(nullptr, "完成", "PDF表格已生成: output_table.pdf");
字体文件放入资源路径,字体下载网站GitCode - 全球开发者的开源社区,开源代码托管平台
类实现
.cpp文件
#include "PdfReportGenerator.h"
bool PdfReportGenerator::parseLogFile(const QString &filename, QVector<LogEntry> &entries) {
QFile file(filename);
if (!file.open(QIODevice::ReadOnly)) return false;
QTextStream in(&file);
in.setCodec("UTF-8");
in.readLine(); // 跳过标题行
while (!in.atEnd()) {
QString line = in.readLine().trimmed();
if (line.isEmpty()) continue;
QStringList parts = line.split("\t", Qt::SkipEmptyParts);
if (parts.size() < 6) continue;
LogEntry entry;
entry.command = parts[0].trimmed();
entry.frame = parts[1].trimmed();
entry.success = parts[2].trimmed().toInt();
entry.fail = parts[3].trimmed().toInt();
entry.timeout = parts[4].trimmed();
entry.duration = parts[5].replace("ms", "").trimmed().toInt();
entry.gapPos = (parts.size() > 6) ? parts[6].trimmed() : "";
entries.append(entry);
}
return true;
}
void PdfReportGenerator::createPdfWithTable(const QVector<LogEntry> &entries) {
// 创建文档对象
QTextDocument doc;
QTextCursor cursor(&doc);
// 设置中文字体
QFont font("SimSun", 10);
doc.setDefaultFont(font);
// 添加标题
cursor.insertText("日志数据报表\n", QTextCharFormat());
cursor.insertBlock();
// 创建表格(列数=7,行数=数据行数+1)
QTextTable *table = cursor.insertTable(entries.size() + 1, 7);
// 设置表头
QStringList headers = {"命令", "帧/时间/次数", "成功次数",
"失败次数", "是否超时", "消耗时间", "缝隙位置"};
for (int i = 0; i < headers.size(); ++i) {
QTextTableCell cell = table->cellAt(0, i);
QTextCursor cellCursor = cell.firstCursorPosition();
cellCursor.insertText(headers[i]);
cell.format().setBackground(Qt::lightGray); // 表头背景色
}
// 填充数据
for (int row = 0; row < entries.size(); ++row) {
const LogEntry &entry = entries[row];
QStringList rowData = {
entry.command,
entry.frame,
QString::number(entry.success),
QString::number(entry.fail),
entry.timeout,
QString::number(entry.duration) + "ms",
entry.gapPos
};
for (int col = 0; col < rowData.size(); ++col) {
QTextTableCell cell = table->cellAt(row + 1, col);
QTextCursor cellCursor = cell.firstCursorPosition();
cellCursor.insertText(rowData[col]);
// 数字列右对齐
if (col >= 2 && col <= 5) {
QTextBlockFormat format;
format.setAlignment(Qt::AlignRight);
cellCursor.setBlockFormat(format);
}
}
}
// 设置表格样式
QTextTableFormat tableFormat;
tableFormat.setHeaderRowCount(1);
tableFormat.setBorderStyle(QTextFrameFormat::BorderStyle_Solid);
tableFormat.setBorder(1);
table->setFormat(tableFormat);
// 导出PDF
QPrinter printer(QPrinter::HighResolution);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName("output_table.pdf");
printer.setPageSize(QPageSize(QPageSize::A4));
doc.print(&printer);
}
.h文件
#ifndef PDFREPORTGENERATOR_H
#define PDFREPORTGENERATOR_H
#include <QApplication>
#include <QFile>
#include <QTextStream>
#include <QTextDocument>
#include <QTextTable>
#include <QPrinter>
#include <QFontDatabase>
#include <QPdfWriter>
#include <QPainter>
#include "qcustomplot.h"
struct LogEntry {
QString command;
QString frame;
int success;
int fail;
QString timeout;
int duration;
QString gapPos;
};
class PdfReportGenerator : public QObject {
public:
void createPdfWithTable(const QVector<LogEntry> &entries);
bool parseLogFile(const QString &filename, QVector<LogEntry> &entries);
};
#endif // PDFREPORTGENERATOR_H
实现效果