十六、Qt之保存成PDF(表格)

PdfAPI.h

#ifndef PDFAPI_H
#define PDFAPI_H

#include <QObject>
#include <QMutex>
#include <QStringList>
#include <QPrinter>

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);

};

#endif // PDFAPI_H

PdfAPI.cpp

#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif

#include "pdfapi.h"
#include "myhelper.h"

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));
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章