Как сохранить график из widget в PDF или график Excel

Имеется какой-либо график, построенный по данным из таблицы tableWidget.

Как сохранить построенный график в PDF или в Excel ?


Ответы (1 шт):

Автор решения: S. Nick

Как вариант, сохранить график из widget в PDF.

ReportLab PDF Library - это программная библиотека, которая позволяет напрямую создавать документы в формате Adobe Portable Document Format (PDF) с использованием языка программирования Python. Он также создает диаграммы и графики данных в различных растровых и векторных форматах, а также в формате PDF. ...

pip install reportlab

import sys
from datetime import datetime
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.Qt import *

from pyqtgraph import PlotWidget, plot
import pyqtgraph as pg

from reportlab.platypus import Image, SimpleDocTemplate, Paragraph
from reportlab.lib.pagesizes import A4, portrait, letter
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_JUSTIFY, TA_LEFT, TA_CENTER


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(640, 498)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
        self.tabWidget.setObjectName("tabWidget")
        self.tab = QtWidgets.QWidget()
        self.tab.setObjectName("tab")
        self.gridLayout_5 = QtWidgets.QGridLayout(self.tab)
        self.gridLayout_5.setObjectName("gridLayout_5")
        self.tableWidget_3 = QtWidgets.QTableWidget(self.tab)
        self.tableWidget_3.setObjectName("tableWidget_3")
        self.tableWidget_3.setColumnCount(9)
        self.tableWidget_3.setRowCount(1)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_3.setVerticalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_3.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_3.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_3.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_3.setHorizontalHeaderItem(3, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_3.setHorizontalHeaderItem(4, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_3.setHorizontalHeaderItem(5, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_3.setHorizontalHeaderItem(6, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_3.setHorizontalHeaderItem(7, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_3.setHorizontalHeaderItem(8, item)
        self.gridLayout_5.addWidget(self.tableWidget_3, 0, 0, 1, 1)
        self.gridLayout_21 = QtWidgets.QGridLayout()
        self.gridLayout_21.setObjectName("gridLayout_21")
        self.groupBox = QtWidgets.QGroupBox(self.tab)
        self.groupBox.setObjectName("groupBox")
        self.gridLayout_4 = QtWidgets.QGridLayout(self.groupBox)
        self.gridLayout_4.setObjectName("gridLayout_4")
        self.pushButton_11 = QtWidgets.QPushButton(self.groupBox)
        self.pushButton_11.setObjectName("pushButton_11")
        self.gridLayout_4.addWidget(self.pushButton_11, 2, 0, 1, 1)
        
        self.pushButton_12 = QtWidgets.QPushButton(self.groupBox)
        self.pushButton_12.setObjectName("pushButton_12")
        self.gridLayout_4.addWidget(self.pushButton_12, 3, 0, 1, 1)        
        
        self.pushButton_9 = QtWidgets.QPushButton(self.groupBox)
        self.pushButton_9.setObjectName("pushButton_9")
        self.gridLayout_4.addWidget(self.pushButton_9, 0, 0, 1, 1)
        self.pushButton_10 = QtWidgets.QPushButton(self.groupBox)
        self.pushButton_10.setObjectName("pushButton_10")
        self.gridLayout_4.addWidget(self.pushButton_10, 1, 0, 1, 1)
        self.gridLayout_21.addWidget(self.groupBox, 0, 1, 1, 1)
        self.tabWidget_2 = QtWidgets.QTabWidget(self.tab)
        self.tabWidget_2.setObjectName("tabWidget_2")
        self.tab_3 = QtWidgets.QWidget()
        self.tab_3.setObjectName("tab_3")
        self.gridLayout_3 = QtWidgets.QGridLayout(self.tab_3)
        self.gridLayout_3.setObjectName("gridLayout_3")
        self.gridLayout_8 = QtWidgets.QGridLayout()
        self.gridLayout_8.setObjectName("gridLayout_8")
        self.widget = QtWidgets.QWidget(self.tab_3)
        self.widget.setObjectName("widget")
        self.gridLayout_8.addWidget(self.widget, 0, 0, 1, 1)
        self.gridLayout_3.addLayout(self.gridLayout_8, 0, 0, 1, 1)
        self.tabWidget_2.addTab(self.tab_3, "")
        self.tab_4 = QtWidgets.QWidget()
        self.tab_4.setObjectName("tab_4")
        self.gridLayout_6 = QtWidgets.QGridLayout(self.tab_4)
        self.gridLayout_6.setObjectName("gridLayout_6")
        self.tabWidget_2.addTab(self.tab_4, "")
        self.gridLayout_21.addWidget(self.tabWidget_2, 0, 0, 1, 1)
        self.gridLayout_5.addLayout(self.gridLayout_21, 1, 0, 1, 1)
        self.tabWidget.addTab(self.tab, "")
        self.tab_2 = QtWidgets.QWidget()
        self.tab_2.setObjectName("tab_2")
        self.tabWidget.addTab(self.tab_2, "")
        self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 640, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.tabWidget_2.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        item = self.tableWidget_3.verticalHeaderItem(0)
        item.setText(_translate("MainWindow", "1"))
        item = self.tableWidget_3.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "1"))
        item = self.tableWidget_3.horizontalHeaderItem(1)
        item.setText(_translate("MainWindow", "2"))
        item = self.tableWidget_3.horizontalHeaderItem(2)
        item.setText(_translate("MainWindow", "3"))
        item = self.tableWidget_3.horizontalHeaderItem(3)
        item.setText(_translate("MainWindow", "4"))
        item = self.tableWidget_3.horizontalHeaderItem(4)
        item.setText(_translate("MainWindow", "5"))
        item = self.tableWidget_3.horizontalHeaderItem(5)
        item.setText(_translate("MainWindow", "6"))
        item = self.tableWidget_3.horizontalHeaderItem(6)
        item.setText(_translate("MainWindow", "7"))
        item = self.tableWidget_3.horizontalHeaderItem(7)
        item.setText(_translate("MainWindow", "8"))
        item = self.tableWidget_3.horizontalHeaderItem(8)
        item.setText(_translate("MainWindow", "9"))
        self.groupBox.setTitle(_translate("MainWindow", "GroupBox"))
        self.pushButton_11.setText(_translate("MainWindow", "Просмотреть график"))
        self.pushButton_12.setText(_translate("MainWindow", "График в PDF"))
        self.pushButton_9.setText(_translate("MainWindow", "Добавить "))
        self.pushButton_10.setText(_translate("MainWindow", "Удалить"))
        
        self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_3), _translate("MainWindow", "График"))
        self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_4), _translate("MainWindow", "Tab 2"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Tab 1"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Tab 2"))


class Widget(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        # Добавить/удалить строку в tableWidget_3
        self.pushButton_9.clicked.connect(self.buttonAdd_2)
        self.pushButton_10.clicked.connect(self.buttonDelete_2)
        # Создания графиков (Ph,Fe, CO2)
        self.pushButton_11.clicked.connect(self.buttonChart_Ph)
# График в PDF
        self.pushButton_12.clicked.connect(self.buttonSave)

        for row in range(self.tableWidget_3.rowCount()):
            date_from = QtWidgets.QDateTimeEdit()
            date_from.setDateTime(
                QtCore.QDateTime(QtCore.QDate(2021, 8, 26),
                                 QtCore.QTime(15, 12, 33))
            )
            self.tableWidget_3.setCellWidget(row, 0, date_from)

        for row in range(self.tableWidget_3.rowCount()):
            date_from = QDateTimeEdit()
            date_from.setDateTime(QDateTime(QDate(2021, 9, 2)))
            date_from.dateTimeChanged.connect(
                lambda dateTime, row=row: self.date_changed(dateTime, row))
            self.tableWidget_3.setCellWidget(row, 0, date_from)
        self.dateTime0 = self.tableWidget_3.cellWidget(0, 0).dateTime()

    # Расчет времени от начального значения
    def date_changed(self, dateTime, row):
        if row == 0:
            self.dateTime0 = self.tableWidget_3.cellWidget(row, 0).dateTime()
            for row in range(1, self.tableWidget_3.rowCount()):
                dateTime2 = self.tableWidget_3.cellWidget(row, 0).dateTime()
                item = QTableWidgetItem()
                item.setData(Qt.DisplayRole,
                             self.dateTime0.secsTo(dateTime2) / 60. / 60.)
                self.tableWidget_3.setItem(row, 1, item)
            return

        dateTime2 = self.tableWidget_3.cellWidget(row, 0).dateTime()
        item = QTableWidgetItem()
        item.setData(Qt.DisplayRole,
                     self.dateTime0.secsTo(dateTime2) / 60. / 60.)
        self.tableWidget_3.setItem(row, 1, item)

    # Кнопка дабовляющая строку в таблицу tableWidget_3
    def buttonAdd_2(self):
        rowPosition = self.tableWidget_3.rowCount()
        self.tableWidget_3.insertRow(rowPosition)
        date_from = QtWidgets.QDateTimeEdit()
        dateTime = QtCore.QDateTime().currentDateTime()
        date_from.setDateTime(dateTime)
        date_from.dateTimeChanged.connect(
            lambda dateTime, row=rowPosition:
            self.date_changed(dateTime, row))
        self.tableWidget_3.setCellWidget(rowPosition, 0, date_from)

    # Кнопка удаляющая строку в таблицу tableWidget_3
    def buttonDelete_2(self):
        if self.tableWidget_3.rowCount() > 0:
            self.tableWidget_3.removeRow(self.tableWidget_3.rowCount() - 1)

    def buttonChart_Ph(self):
        data_for_word = []                            
        data_for_word_2 = []                         

        rows = self.tableWidget_3.rowCount()
        for row in range(rows):
            item_N2 = self.tableWidget_3.item(row, 1)
            _data_N2 = item_N2.data(Qt.DisplayRole) if item_N2 else '0'
            item_N3 = self.tableWidget_3.item(row, 2)
            _data_N3 = item_N3.data(Qt.DisplayRole) if item_N3 else '0'
            data_for_word.append([_data_N2, _data_N3])
            item_N5 = self.tableWidget_3.item(row, 4)
            _data_N5 = item_N5.data(Qt.DisplayRole) if item_N5 else '0'            
            data_for_word_2.append([_data_N2, _data_N5])
            
        #print(f'data_for_word   = {data_for_word}') 
        #print(f'data_for_word_2 = {data_for_word_2}')

        self.x, self.y = [], []
        for x, y in data_for_word:
            #print(f'x={x}; y={y}')
            self.x.append(float(x))
            self.y.append(float(y))
        self.widget = pg.PlotWidget()
        pen = pg.mkPen(color=(255, 0, 0), width=2)
        self.widget.plot(
            x=self.x,
            y=self.y, pen=pen, symbol='o'
        )
        w = self.findChild(PlotWidget, 'widget')
        if w: w.deleteLater()
        
        self.gridLayout_8.addWidget(
            self.widget,
            0, 0, 1, 1, alignment=Qt.AlignCenter
            )
        self.widget.setFixedSize(260, 238)
        self.widget.setBackground('w')
        self.widget.setTitle("Ph, ед.Ph", color="b", size="10pt")
        styles = {"color": "#f00", "font-size": "15px"}
        self.widget.setLabel("left", "Ph", **styles)
        self.widget.setLabel("bottom", "Hour(H)", **styles)
        self.widget.showGrid(x=True, y=True)

        self.x, self.y = [], []
        for x, y in data_for_word_2:
            #print(f'x={x}; y={y}')
            self.x.append(float(x))
            self.y.append(float(y))

        pen = pg.mkPen(color=(0, 255, 111), width=2)
        self.widget.plot(
            x=self.x,
            y=self.y, pen=pen, symbol='o'
        )

# График в PDF vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
    def buttonSave(self):
        fname = 'q1329547.png'                 
        pixmap = QPixmap(self.widget.size())
        self.widget.render(QPainter(pixmap))
        pixmap.save(fname)

        path = 'q1329547.pdf'
        self.pdf = SimpleDocTemplate(
            path, 
            pagesize=letter, 
            rightMargin=0, 
            leftMargin=30, 
            topMargin=70, 
            bottomMargin=0,
            title="ГРАФИК",
        )
        self.pdf.pagesize = portrait(A4)
 
        self.image = Image(fname) 
        self.image.drawWidth = self.widget.size().width()
        self.image.drawHeight = self.widget.size().height()
               
        styles = getSampleStyleSheet() 
        styleH = styles["Heading2"]
        styleH.alignment = TA_CENTER   

        text = '''
            <b>Hello World: </b> 
            <img src="https://www.python.org/static/community_logos/python-powered-w-70x28.png" width="70" height="28"/>
        '''
        
        document = []
        document.append(Paragraph(text, styleH))
        document.append(self.image)

        self.pdf.build(document) 

    
if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setStyle("Windows")
    ex = Widget()
    ex.setWindowTitle("SAFTD ...")
    ex.resize(640, 540)
    ex.show()
    sys.exit(app.exec_())

введите сюда описание изображения

→ Ссылка