1. 程式人生 > 其它 >Qt資料庫應用19-圖片轉pdf

Qt資料庫應用19-圖片轉pdf

一、前言

使用者的需求真的是千奇百怪,剛做完不同頁面橫向縱向排版的需求,又來個需要圖片轉pdf的需求,提供靜態函式直接使用。 經過這麼些年的社會的毒打,我的原則是:使用者是上帝和大爺,儘量站在使用者的角度換位思考,只要是合理或者基本合理的需求,甚至說只要不是太過分,給錢就幹。

接到這個需求的時候,第一時間想到的就是用QPainter繪製圖片到印表機物件,之前就用QPainter繪製了200多個自定義控制元件,對於QPainter如何繪製,心中早有程式碼自動生成了,現在看到真實世界的很多東西,尤其是圖形,都自動在腦海中轉成了程式碼,比如公交車上的路線圖,到某個站點自動點亮。既然QPrinter支援QPainter繪製,這兩者結合就是對程式設計師的繪製功底要求高,熟悉了以後繪製起來還是非常順手的,因為思路和方法完全一樣。

在封裝的本函式中,可以直接傳入圖片檔名稱,需要儲存的檔名,如果儲存的檔名為空,則取同名檔案,就拓展名格式不一樣,還可以傳入資原始檔中的圖片,可以設定如何縮放,是拉伸填充還是等比例縮放等。

二、功能特點

  1. 元件同時集成了匯出資料到csv、xls、pdf和列印資料。
  2. 所有操作全部提供靜態方法無需new,資料和屬性等各種引數設定採用結構體資料,極為方便。
  3. 同時支援QTableView、QTableWidget、QStandardItemModel、QSqlTableModel等資料來源。
  4. 提供靜態方法直接傳入QTableView、QTableWidget控制元件,自動識別列名、列寬和資料內容。
  5. 每組功能都提供單獨的完整的示例,註釋詳細,非常適合各階段Qter程式設計師。
  6. 原創匯出資料機制,不依賴任何office元件或者作業系統等第三方庫,支援嵌入式linux。
  7. 速度超快,9個欄位10萬行資料只需要2秒鐘完成。
  8. 只需要四個步驟即可開始急速匯出海量資料比如100W條記錄到Excel。
  9. 同時提供直接寫入資料介面和多執行緒寫入資料介面,不卡主介面。
  10. 可設定標題、副標題、表名。
  11. 可設定匯出資料的欄位名、列名、列寬。
  12. 可設定末尾列自動拉伸填充,預設拉伸更美觀。
  13. 可設定是否啟用校驗過濾資料,啟用後符合規則的資料特殊顏色顯示。
  14. 可指定校驗的列、校驗規則、校驗值、校驗值資料型別。
  15. 校驗規則支援 精確等於==、大於>、大於等於>=、小於<、小於等於<=、不等於!=、包含contains。
  16. 校驗值資料型別支援 整型int、浮點型float、雙精度型double,預設文字字串型別。
  17. 可設定隨機背景顏色及需要隨機背景色的列集合。
  18. 支援分組輸出資料,比如按照裝置分組輸出資料,方便檢視。
  19. 可設定csv分隔符、行內容分隔符、子內容分隔符。
  20. 可設定邊框寬度、自動填資料型別,預設自動資料型別開啟。
  21. 可設定是否開啟資料單元格樣式,預設不開啟,不開啟可以節約大概30%的檔案體積。
  22. 可設定橫向排版、紙張邊距等,比如匯出到pdf以及列印資料。
  23. 提供圖文混排匯出資料到pdf以及列印示例,自動分頁,支援多圖。
  24. 提供一個列印樣板中同時包括橫向縱向排版示例。
  25. 提供靜態函式將控制元件截圖匯出到pdf檔案。
  26. 提供靜態函式將圖片轉成pdf檔案。
  27. 提供靜態函式將csv檔案轉成xls檔案,支援列寬表名等引數設定。
  28. 針對每列可分別設定欄位對齊樣式、內容對齊樣式,包括左對齊、居中對齊、右對齊。
  29. 靈活性超高,可自由更改原始碼設定對齊方式、文字顏色、背景顏色等。
  30. 支援任意excel表格軟體,包括但不限於excel2003-2021、wps、openoffice等。
  31. 純Qt編寫,支援任意Qt版本+任意編譯器+任意系統。

三、體驗地址

  1. 體驗地址:https://pan.baidu.com/s/1ZxG-oyUKe286LPMPxOrO2A 提取碼:o05q 檔名:bin_dataout.zip
  2. 國內站點:https://gitee.com/feiyangqingyun
  3. 國際站點:https://github.com/feiyangqingyun
  4. 個人主頁:https://blog.csdn.net/feiyangqingyun
  5. 知乎主頁:https://www.zhihu.com/people/feiyangqingyun/

四、效果圖

五、相關程式碼

void DataOther::toPdf(const QPixmap &pixmap, const QString &fileName, int scale)
{
    QPrinter printer(QPrinter::HighResolution);
    if (scale > 1) {
        printer.setResolution(96);
    }
    printer.setFullPage(false);
    printer.setOutputFormat(QPrinter::PdfFormat);
    printer.setOutputFileName(fileName);
#if (QT_VERSION >= QT_VERSION_CHECK(5,3,0))
    printer.setPageSize(QPageSize(QPageSize::A4));
    printer.setPageOrientation(QPageLayout::Portrait);
#else
    printer.setPaperSize(QPrinter::A4);
    printer.setOrientation(QPrinter::Portrait);
#endif

    //調整圖片大小比如等比例縮放拉伸填充等
    QRectF rect = printer.pageRect(QPrinter::DevicePixel);
    QPixmap pix = pixmap;

    //儲存原圖看下效果
#if 0
    QString file = fileName;
    file.replace("pdf", "png");
    pix.save(file, "png");
#endif

    if (scale == 0) {
        //pix = pix.scaled(rect.width(), rect.height(), Qt::KeepAspectRatio, Qt::FastTransformation);
        pix = pix.scaled(rect.width(), rect.height(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
    } else if (scale == 1) {
        pix = pix.scaled(rect.width(), rect.height());
    }

    QPainter painter;
    painter.begin(&printer);

    int x = 0;
    int y = 0;
    //圖片寬度小於繪製區域寬度沒有縮放處理過的圖片 才需要按照比例自動居中繪製
    if (pixmap.width() < rect.width() && scale > 1) {
        x = rect.center().x() - pix.width() / 2;
        //y = rect.center().y() - pix.height() / 2;
    }

    painter.drawPixmap(QPoint(x, y), pix);
    painter.end();
}

void DataOther::widgetToPdf(QWidget *widget, const QString &fileName, int scale)
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
    QPixmap pixmap = QApplication::primaryScreen()->grabWindow(widget->winId());
#else
    QPixmap pixmap = QPixmap::grabWindow(widget->winId());
#endif
    toPdf(pixmap, fileName, scale);
}

QString DataOther::imageToPdf(const QString &imageFile, const QString &pdfFile, int scale)
{
    //為空則同名檔案
    QString fileName = pdfFile;
    if (fileName.isEmpty()) {
        fileName = imageFile;
        fileName.replace("." + QFileInfo(imageFile).suffix(), ".pdf");
    }

    //資原始檔則當前目錄下
    if (imageFile.startsWith(":/")) {
        fileName = qApp->applicationDirPath() + "/" + QFileInfo(imageFile).baseName() + ".pdf";
    }

    toPdf(QPixmap(imageFile), fileName, scale);
    return fileName;
}