PdfAPI.h
class PdfAPI : public QObject
{
Q_OBJECT
private:
explicit PdfAPI(QObject *parent = 0);
static PdfAPI *_instance;
QStringList html;
public:
static PdfAPI *Instance() {
static QMutex mutex;
if (!_instance) {
QMutexLocker locker(&mutex);
if (!_instance) {
_instance = new PdfAPI;
}
}
return _instance;
}
/**
* @brief SavePdf 将数据保存成PDF表格
* @param fileName 文件名
* @param title 表格标题
* @param subTitle 表格副标题
* @param columnNames 列名
* @param columnWidths 列宽
* @param content 数据内容
* @param landscape 纸张是否横向
* @param check 是否给某列加特殊样式
* @param pageSize 纸张类型
*/
void SavePdf(QString fileName, QString title, QString subTitle,
QList<QString> columnNames, QList<int> columnWidths,
QStringList content, bool landscape, bool check,
QPrinter::PageSize pageSize = QPrinter::A4);
void SavePdf(QString fileName, QString title,
QList<QString> columnNames, QList<int> columnWidths,
QStringList subTitle1, QStringList subTitle2,
QStringList content, bool landscape, bool check,
QPrinter::PageSize pageSize = QPrinter::A4);
};
// PDFAPI_H
PdfAPI.cpp
PdfAPI *PdfAPI::_instance = 0;
PdfAPI::PdfAPI(QObject *parent) : QObject(parent)
{
}
void PdfAPI::SavePdf(QString fileName, QString title, QString subTitle, QList<QString> columnNames,
QList<int> columnWidths, QStringList content, bool landscape, bool check,
QPrinter::PageSize pageSize)
{
//计算行数列数
int columnCount = columnNames.count();
int rowCount = content.count();
//清空原有数据,确保每次都是新的数据
html.clear();
//表格开始
html.append("<table border='0.5' cellspacing='0' cellpadding='3'>");
//标题占一行,居中显示
if (title.length() > 0) {
html.append(QString("<tr><td align='center' style='vertical-align:middle;font-weight:bold;' colspan='%1'>")
.arg(columnCount));
html.append(title);
html.append("</td></tr>");
}
//副标题占一行,左对齐显示
if (subTitle.length() > 0) {
html.append(QString("<tr><td align='left' style='vertical-align:middle;' colspan='%1'>")
.arg(columnCount));
html.append(subTitle);
html.append("</td></tr>");
}
//循环写入字段名,字段名占一行,居中显示
if (columnCount > 0) {
html.append("<tr>");
for (int i = 0; i < columnCount; i++) {
html.append(QString("<td width='%1' bgcolor='lightgray' align='center' style='vertical-align:middle;'>")
.arg(columnWidths.at(i)));
html.append(columnNames.at(i));
html.append("</td>");
}
html.append("</tr>");
}
//循环一行行构建数据
for (int i = 0; i < rowCount; i++) {
QStringList value = content.at(i).split(";");
html.append("<tr>");
if (check) {
if (value.at(value.count() - 1) == "历史记录") {
for (int j = 0; j < columnCount; j++) {
html.append(QString("<td width='%1' align='center' style='vertical-align:middle;'>"
"<font color='red'>").arg(columnWidths.at(j)));
html.append(value.at(j));
html.append("</font></td>");
}
} else {
for (int j = 0; j < columnCount; j++) {
html.append(QString("<td width='%1' align='center' style='vertical-align:middle;'>")
.arg(columnWidths.at(j)));
html.append(value.at(j));
html.append("</td>");
}
}
} else {
for (int j = 0; j < columnCount; j++) {
html.append(QString("<td width='%1' align='center' style='vertical-align:middle;'>")
.arg(columnWidths.at(j)));
html.append(value.at(j));
html.append("</td>");
}
}
html.append("</tr>");
}
html.append("</table>");
//调用打印机打印PDF
QPrinter printer;
//设置纸张规格
printer.setPageSize(pageSize);
//设置横向纵向及页边距
if (landscape) {
//Orientation:纸张方向,有QPrinter::Portrait(纵向)和QPrinter::Landscape(横向)
printer.setOrientation(QPrinter::Landscape);
printer.setPageMargins(10, 10, 10, 11, QPrinter::Millimeter);
} else {
printer.setOrientation(QPrinter::Portrait);
printer.setPageMargins(10, 10, 10, 15, QPrinter::Millimeter);
}
//设置输出格式为PDF
printer.setOutputFormat(QPrinter::PdfFormat);
//设置输出文件保存位置
printer.setOutputFileName(fileName);
QTextDocument textDocument;
textDocument.setHtml(html.join(""));
textDocument.print(&printer);
textDocument.end();
}
void PdfAPI::SavePdf(QString fileName, QString title, QList<QString> columnNames,
QList<int> columnWidths, QStringList subTitle1, QStringList subTitle2,
QStringList content, bool landscape, bool check, QPrinter::PageSize pageSize)
{
//计算列数
int columnCount = columnNames.count();
//清空原有数据,确保每次都是新的数据
html.clear();
//表格开始
html.append("<table border='0.5' cellspacing='0' cellpadding='3'>");
//标题占一行,居中显示
if (title.length() > 0) {
html.append(QString("<tr><td align='center' style='vertical-align:middle;font-weight:bold;' colspan='%1'>")
.arg(columnCount));
html.append(title);
html.append("</td></tr>");
}
//循环添加副标题/字段名/内容
int count = content.count();
for (int i = 0; i < count; i++) {
//加个空行隔开
html.append(QString("<tr><td colspan='%1'>").arg(columnCount));
html.append("</td></tr>");
//副标题1
if (subTitle1.count() > 0 && subTitle1.count() > i) {
if (subTitle1.at(i).length() > 0) {
html.append(QString("<tr><td align='left' style='vertical-align:middle;' colspan='%1'>")
.arg(columnCount));
html.append(subTitle1.at(i));
html.append("</td></tr>");
}
}
//副标题2
if (subTitle2.count() > 0 && subTitle2.count() > i) {
if (subTitle2.at(i).length() > 0) {
html.append(QString("<tr><td align='left' style='vertical-align:middle;' colspan='%1'>")
.arg(columnCount));
html.append(subTitle2.at(i));
html.append("</td></tr>");
}
}
//逐个添加字段名称
if (columnCount > 0) {
html.append("<tr>");
for (int i = 0; i < columnCount; i++) {
html.append(QString("<td width='%1' bgcolor='lightgray' align='center' style='vertical-align:middle;'>")
.arg(columnWidths.at(i)));
html.append(columnNames.at(i));
html.append("</td>");
}
html.append("</tr>");
}
QStringList list = content.at(i).split(";");
//逐个添加数据
int rowCount = list.count();
for (int j = 0; j < rowCount; j++) {
html.append("<tr>");
QString temp = list.at(j);
QStringList value = temp.split("|");
int valueCount = value.count();
if (check) {
//如果是历史记录则文字红色
if (value.at(valueCount - 1) == "1") {
for (int k = 0; k < valueCount - 1; k++) {
html.append(QString("<td width='%1' align='center' style='vertical-align:middle;'>"
"<font color='red'>").arg(columnWidths.at(k)));
html.append(value.at(k));
html.append("</font></td>");
}
} else {
for (int k = 0; k < valueCount - 1; k++) {
html.append(QString("<td width='%1' align='center' style='vertical-align:middle;'>")
.arg(columnWidths.at(k)));
html.append(value.at(k));
html.append("</td>");
}
}
} else {
for (int k = 0; k < valueCount; k++) {
html.append(QString("<td width='%1' align='center' style='vertical-align:middle;'>")
.arg(columnWidths.at(k)));
html.append(value.at(k));
html.append("</td>");
}
}
html.append("</tr>");
}
}
html.append("</table>");
//调用打印机打印PDF
QPrinter printer;
//设置纸张规格
printer.setPageSize(pageSize);
//设置横向纵向及页边距
if (landscape) {
printer.setOrientation(QPrinter::Landscape);
printer.setPageMargins(10, 10, 10, 11, QPrinter::Millimeter);
} else {
printer.setOrientation(QPrinter::Portrait);
printer.setPageMargins(10, 10, 10, 15, QPrinter::Millimeter);
}
//设置输出格式为PDF
printer.setOutputFormat(QPrinter::PdfFormat);
//设置输出文件保存位置
printer.setOutputFileName(fileName);
QTextDocument textDocument;
textDocument.setHtml(html.join(""));
textDocument.print(&printer);
textDocument.end();
}
使用案例
void frmAlarm::on_btnPdf_clicked()
{
QString type = "所有告警记录";
QString defaultName = QString("%1/%2.pdf").arg(App::AppPath).arg(STRDATETIME);
QString file = QFileDialog::getSaveFileName(this, "保存文件", defaultName, "Pdf(*.pdf)");
if (file.length() == 0) {
return;
}
QStringList content = GetContent();
int rowCount = content.count() ;
//判断数据量是否超过500条,超过则弹出提示
if (rowCount > 500) {
QString msg = QString("要导出的数据共 %1 条,请耐心等待!确定要导出数据吗?").arg(rowCount);
if (myHelper::ShowMessageBoxQuestion(msg) != 1) {
return;
}
}
QList<int> columnWidths;
columnWidths.append(150);
columnWidths.append(120);
columnWidths.append(180);
columnWidths.append(100);
columnWidths.append(150);
PdfAPI::Instance()->SavePdf(file, type, "", columnNames, columnWidths, content, false, false);
QString msg = QString("导出%1到Pdf").arg(type);
DBHelper::AddEventInfoUser(msg);
if (myHelper::ShowMessageBoxQuestion(msg + "成功!确定现在就打开吗?") == 1) {
// 打开电脑中的文件
QString url = QString("file:///%1").arg(file);
QDesktopServices::openUrl(QUrl(url, QUrl::TolerantMode));
}
}