使用Python3+PyQT5+Pyserial 实现简单的串口工具方法


Posted in Python onFebruary 13, 2019

练手项目,先上图

使用Python3+PyQT5+Pyserial 实现简单的串口工具方法

先实现一个简单的串口工具,为之后的上位机做准备

代码如下:

github 下载地址

pyserial_demo.py

import sys
import serial
import serial.tools.list_ports
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QMessageBox
from PyQt5.QtCore import QTimer
from ui_demo_1 import Ui_Form


class Pyqt5_Serial(QtWidgets.QWidget, Ui_Form):
  def __init__(self):
    super(Pyqt5_Serial, self).__init__()
    self.setupUi(self)
    self.init()
    self.setWindowTitle("串口小助手")
    self.ser = serial.Serial()
    self.port_check()

    # 接收数据和发送数据数目置零
    self.data_num_received = 0
    self.lineEdit.setText(str(self.data_num_received))
    self.data_num_sended = 0
    self.lineEdit_2.setText(str(self.data_num_sended))

  def init(self):
    # 串口检测按钮
    self.s1__box_1.clicked.connect(self.port_check)

    # 串口信息显示
    self.s1__box_2.currentTextChanged.connect(self.port_imf)

    # 打开串口按钮
    self.open_button.clicked.connect(self.port_open)

    # 关闭串口按钮
    self.close_button.clicked.connect(self.port_close)

    # 发送数据按钮
    self.s3__send_button.clicked.connect(self.data_send)

    # 定时发送数据
    self.timer_send = QTimer()
    self.timer_send.timeout.connect(self.data_send)
    self.timer_send_cb.stateChanged.connect(self.data_send_timer)

    # 定时器接收数据
    self.timer = QTimer(self)
    self.timer.timeout.connect(self.data_receive)

    # 清除发送窗口
    self.s3__clear_button.clicked.connect(self.send_data_clear)

    # 清除接收窗口
    self.s2__clear_button.clicked.connect(self.receive_data_clear)

  # 串口检测
  def port_check(self):
    # 检测所有存在的串口,将信息存储在字典中
    self.Com_Dict = {}
    port_list = list(serial.tools.list_ports.comports())
    self.s1__box_2.clear()
    for port in port_list:
      self.Com_Dict["%s" % port[0]] = "%s" % port[1]
      self.s1__box_2.addItem(port[0])
    if len(self.Com_Dict) == 0:
      self.state_label.setText(" 无串口")

  # 串口信息
  def port_imf(self):
    # 显示选定的串口的详细信息
    imf_s = self.s1__box_2.currentText()
    if imf_s != "":
      self.state_label.setText(self.Com_Dict[self.s1__box_2.currentText()])

  # 打开串口
  def port_open(self):
    self.ser.port = self.s1__box_2.currentText()
    self.ser.baudrate = int(self.s1__box_3.currentText())
    self.ser.bytesize = int(self.s1__box_4.currentText())
    self.ser.stopbits = int(self.s1__box_6.currentText())
    self.ser.parity = self.s1__box_5.currentText()

    try:
      self.ser.open()
    except:
      QMessageBox.critical(self, "Port Error", "此串口不能被打开!")
      return None

    # 打开串口接收定时器,周期为2ms
    self.timer.start(2)

    if self.ser.isOpen():
      self.open_button.setEnabled(False)
      self.close_button.setEnabled(True)
      self.formGroupBox1.setTitle("串口状态(已开启)")

  # 关闭串口
  def port_close(self):
    self.timer.stop()
    self.timer_send.stop()
    try:
      self.ser.close()
    except:
      pass
    self.open_button.setEnabled(True)
    self.close_button.setEnabled(False)
    self.lineEdit_3.setEnabled(True)
    # 接收数据和发送数据数目置零
    self.data_num_received = 0
    self.lineEdit.setText(str(self.data_num_received))
    self.data_num_sended = 0
    self.lineEdit_2.setText(str(self.data_num_sended))
    self.formGroupBox1.setTitle("串口状态(已关闭)")

  # 发送数据
  def data_send(self):
    if self.ser.isOpen():
      input_s = self.s3__send_text.toPlainText()
      if input_s != "":
        # 非空字符串
        if self.hex_send.isChecked():
          # hex发送
          input_s = input_s.strip()
          send_list = []
          while input_s != '':
            try:
              num = int(input_s[0:2], 16)
            except ValueError:
              QMessageBox.critical(self, 'wrong data', '请输入十六进制数据,以空格分开!')
              return None
            input_s = input_s[2:].strip()
            send_list.append(num)
          input_s = bytes(send_list)
        else:
          # ascii发送
          input_s = (input_s + '\r\n').encode('utf-8')

        num = self.ser.write(input_s)
        self.data_num_sended += num
        self.lineEdit_2.setText(str(self.data_num_sended))
    else:
      pass

  # 接收数据
  def data_receive(self):
    try:
      num = self.ser.inWaiting()
    except:
      self.port_close()
      return None
    if num > 0:
      data = self.ser.read(num)
      num = len(data)
      # hex显示
      if self.hex_receive.checkState():
        out_s = ''
        for i in range(0, len(data)):
          out_s = out_s + '{:02X}'.format(data[i]) + ' '
        self.s2__receive_text.insertPlainText(out_s)
      else:
        # 串口接收到的字符串为b'123',要转化成unicode字符串才能输出到窗口中去
        self.s2__receive_text.insertPlainText(data.decode('iso-8859-1'))

      # 统计接收字符的数量
      self.data_num_received += num
      self.lineEdit.setText(str(self.data_num_received))

      # 获取到text光标
      textCursor = self.s2__receive_text.textCursor()
      # 滚动到底部
      textCursor.movePosition(textCursor.End)
      # 设置光标到text中去
      self.s2__receive_text.setTextCursor(textCursor)
    else:
      pass

  # 定时发送数据
  def data_send_timer(self):
    if self.timer_send_cb.isChecked():
      self.timer_send.start(int(self.lineEdit_3.text()))
      self.lineEdit_3.setEnabled(False)
    else:
      self.timer_send.stop()
      self.lineEdit_3.setEnabled(True)

  # 清除显示
  def send_data_clear(self):
    self.s3__send_text.setText("")

  def receive_data_clear(self):
    self.s2__receive_text.setText("")


if __name__ == '__main__':
  app = QtWidgets.QApplication(sys.argv)
  myshow = Pyqt5_Serial()
  myshow.show()
  sys.exit(app.exec_())

ui_demo_1.py

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'demo_1.ui'
#
# Created by: PyQt5 UI code generator 5.6
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_Form(object):
  def setupUi(self, Form):
    Form.setObjectName("Form")
    Form.resize(707, 458)
    self.formGroupBox = QtWidgets.QGroupBox(Form)
    self.formGroupBox.setGeometry(QtCore.QRect(20, 20, 167, 301))
    self.formGroupBox.setObjectName("formGroupBox")
    self.formLayout = QtWidgets.QFormLayout(self.formGroupBox)
    self.formLayout.setContentsMargins(10, 10, 10, 10)
    self.formLayout.setSpacing(10)
    self.formLayout.setObjectName("formLayout")
    self.s1__lb_1 = QtWidgets.QLabel(self.formGroupBox)
    self.s1__lb_1.setObjectName("s1__lb_1")
    self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.s1__lb_1)
    self.s1__box_1 = QtWidgets.QPushButton(self.formGroupBox)
    self.s1__box_1.setAutoRepeatInterval(100)
    self.s1__box_1.setDefault(True)
    self.s1__box_1.setObjectName("s1__box_1")
    self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.s1__box_1)
    self.s1__lb_2 = QtWidgets.QLabel(self.formGroupBox)
    self.s1__lb_2.setObjectName("s1__lb_2")
    self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.s1__lb_2)
    self.s1__box_2 = QtWidgets.QComboBox(self.formGroupBox)
    self.s1__box_2.setObjectName("s1__box_2")
    self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.s1__box_2)
    self.s1__lb_3 = QtWidgets.QLabel(self.formGroupBox)
    self.s1__lb_3.setObjectName("s1__lb_3")
    self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.s1__lb_3)
    self.s1__box_3 = QtWidgets.QComboBox(self.formGroupBox)
    self.s1__box_3.setObjectName("s1__box_3")
    self.s1__box_3.addItem("")
    self.s1__box_3.addItem("")
    self.s1__box_3.addItem("")
    self.s1__box_3.addItem("")
    self.s1__box_3.addItem("")
    self.s1__box_3.addItem("")
    self.s1__box_3.addItem("")
    self.s1__box_3.addItem("")
    self.s1__box_3.addItem("")
    self.s1__box_3.addItem("")
    self.s1__box_3.addItem("")
    self.s1__box_3.addItem("")
    self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.s1__box_3)
    self.s1__lb_4 = QtWidgets.QLabel(self.formGroupBox)
    self.s1__lb_4.setObjectName("s1__lb_4")
    self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.s1__lb_4)
    self.s1__box_4 = QtWidgets.QComboBox(self.formGroupBox)
    self.s1__box_4.setObjectName("s1__box_4")
    self.s1__box_4.addItem("")
    self.s1__box_4.addItem("")
    self.s1__box_4.addItem("")
    self.s1__box_4.addItem("")
    self.formLayout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.s1__box_4)
    self.s1__lb_5 = QtWidgets.QLabel(self.formGroupBox)
    self.s1__lb_5.setObjectName("s1__lb_5")
    self.formLayout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.s1__lb_5)
    self.s1__box_5 = QtWidgets.QComboBox(self.formGroupBox)
    self.s1__box_5.setObjectName("s1__box_5")
    self.s1__box_5.addItem("")
    self.formLayout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.s1__box_5)
    self.open_button = QtWidgets.QPushButton(self.formGroupBox)
    self.open_button.setObjectName("open_button")
    self.formLayout.setWidget(7, QtWidgets.QFormLayout.SpanningRole, self.open_button)
    self.close_button = QtWidgets.QPushButton(self.formGroupBox)
    self.close_button.setObjectName("close_button")
    self.formLayout.setWidget(8, QtWidgets.QFormLayout.SpanningRole, self.close_button)
    self.s1__lb_6 = QtWidgets.QLabel(self.formGroupBox)
    self.s1__lb_6.setObjectName("s1__lb_6")
    self.formLayout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.s1__lb_6)
    self.s1__box_6 = QtWidgets.QComboBox(self.formGroupBox)
    self.s1__box_6.setObjectName("s1__box_6")
    self.s1__box_6.addItem("")
    self.formLayout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.s1__box_6)
    self.state_label = QtWidgets.QLabel(self.formGroupBox)
    self.state_label.setText("")
    self.state_label.setTextFormat(QtCore.Qt.AutoText)
    self.state_label.setScaledContents(True)
    self.state_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
    self.state_label.setObjectName("state_label")
    self.formLayout.setWidget(2, QtWidgets.QFormLayout.SpanningRole, self.state_label)
    self.verticalGroupBox = QtWidgets.QGroupBox(Form)
    self.verticalGroupBox.setGeometry(QtCore.QRect(210, 20, 401, 241))
    self.verticalGroupBox.setObjectName("verticalGroupBox")
    self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalGroupBox)
    self.verticalLayout.setContentsMargins(10, 10, 10, 10)
    self.verticalLayout.setObjectName("verticalLayout")
    self.s2__receive_text = QtWidgets.QTextBrowser(self.verticalGroupBox)
    self.s2__receive_text.setObjectName("s2__receive_text")
    self.verticalLayout.addWidget(self.s2__receive_text)
    self.verticalGroupBox_2 = QtWidgets.QGroupBox(Form)
    self.verticalGroupBox_2.setGeometry(QtCore.QRect(210, 280, 401, 101))
    self.verticalGroupBox_2.setObjectName("verticalGroupBox_2")
    self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.verticalGroupBox_2)
    self.verticalLayout_2.setContentsMargins(10, 10, 10, 10)
    self.verticalLayout_2.setObjectName("verticalLayout_2")
    self.s3__send_text = QtWidgets.QTextEdit(self.verticalGroupBox_2)
    self.s3__send_text.setObjectName("s3__send_text")
    self.verticalLayout_2.addWidget(self.s3__send_text)
    self.s3__send_button = QtWidgets.QPushButton(Form)
    self.s3__send_button.setGeometry(QtCore.QRect(620, 310, 61, 31))
    self.s3__send_button.setObjectName("s3__send_button")
    self.s3__clear_button = QtWidgets.QPushButton(Form)
    self.s3__clear_button.setGeometry(QtCore.QRect(620, 350, 61, 31))
    self.s3__clear_button.setObjectName("s3__clear_button")
    self.formGroupBox1 = QtWidgets.QGroupBox(Form)
    self.formGroupBox1.setGeometry(QtCore.QRect(20, 340, 171, 101))
    self.formGroupBox1.setObjectName("formGroupBox1")
    self.formLayout_2 = QtWidgets.QFormLayout(self.formGroupBox1)
    self.formLayout_2.setContentsMargins(10, 10, 10, 10)
    self.formLayout_2.setSpacing(10)
    self.formLayout_2.setObjectName("formLayout_2")
    self.label = QtWidgets.QLabel(self.formGroupBox1)
    self.label.setObjectName("label")
    self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label)
    self.label_2 = QtWidgets.QLabel(self.formGroupBox1)
    self.label_2.setObjectName("label_2")
    self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_2)
    self.lineEdit = QtWidgets.QLineEdit(self.formGroupBox1)
    self.lineEdit.setObjectName("lineEdit")
    self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.lineEdit)
    self.lineEdit_2 = QtWidgets.QLineEdit(self.formGroupBox1)
    self.lineEdit_2.setObjectName("lineEdit_2")
    self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.lineEdit_2)
    self.hex_send = QtWidgets.QCheckBox(Form)
    self.hex_send.setGeometry(QtCore.QRect(620, 280, 71, 16))
    self.hex_send.setObjectName("hex_send")
    self.hex_receive = QtWidgets.QCheckBox(Form)
    self.hex_receive.setGeometry(QtCore.QRect(620, 40, 71, 16))
    self.hex_receive.setObjectName("hex_receive")
    self.s2__clear_button = QtWidgets.QPushButton(Form)
    self.s2__clear_button.setGeometry(QtCore.QRect(620, 80, 61, 31))
    self.s2__clear_button.setObjectName("s2__clear_button")
    self.timer_send_cb = QtWidgets.QCheckBox(Form)
    self.timer_send_cb.setGeometry(QtCore.QRect(260, 390, 71, 16))
    self.timer_send_cb.setObjectName("timer_send_cb")
    self.lineEdit_3 = QtWidgets.QLineEdit(Form)
    self.lineEdit_3.setGeometry(QtCore.QRect(350, 390, 61, 20))
    self.lineEdit_3.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
    self.lineEdit_3.setObjectName("lineEdit_3")
    self.dw = QtWidgets.QLabel(Form)
    self.dw.setGeometry(QtCore.QRect(420, 390, 54, 20))
    self.dw.setObjectName("dw")
    self.verticalGroupBox.raise_()
    self.verticalGroupBox_2.raise_()
    self.formGroupBox.raise_()
    self.s3__send_button.raise_()
    self.s3__clear_button.raise_()
    self.formGroupBox.raise_()
    self.hex_send.raise_()
    self.hex_receive.raise_()
    self.s2__clear_button.raise_()
    self.timer_send_cb.raise_()
    self.lineEdit_3.raise_()
    self.dw.raise_()

    self.retranslateUi(Form)
    QtCore.QMetaObject.connectSlotsByName(Form)

  def retranslateUi(self, Form):
    _translate = QtCore.QCoreApplication.translate
    Form.setWindowTitle(_translate("Form", "Form"))
    self.formGroupBox.setTitle(_translate("Form", "串口设置"))
    self.s1__lb_1.setText(_translate("Form", "串口检测:"))
    self.s1__box_1.setText(_translate("Form", "检测串口"))
    self.s1__lb_2.setText(_translate("Form", "串口选择:"))
    self.s1__lb_3.setText(_translate("Form", "波特率:"))
    self.s1__box_3.setItemText(0, _translate("Form", "115200"))
    self.s1__box_3.setItemText(1, _translate("Form", "2400"))
    self.s1__box_3.setItemText(2, _translate("Form", "4800"))
    self.s1__box_3.setItemText(3, _translate("Form", "9600"))
    self.s1__box_3.setItemText(4, _translate("Form", "14400"))
    self.s1__box_3.setItemText(5, _translate("Form", "19200"))
    self.s1__box_3.setItemText(6, _translate("Form", "38400"))
    self.s1__box_3.setItemText(7, _translate("Form", "57600"))
    self.s1__box_3.setItemText(8, _translate("Form", "76800"))
    self.s1__box_3.setItemText(9, _translate("Form", "12800"))
    self.s1__box_3.setItemText(10, _translate("Form", "230400"))
    self.s1__box_3.setItemText(11, _translate("Form", "460800"))
    self.s1__lb_4.setText(_translate("Form", "数据位:"))
    self.s1__box_4.setItemText(0, _translate("Form", "8"))
    self.s1__box_4.setItemText(1, _translate("Form", "7"))
    self.s1__box_4.setItemText(2, _translate("Form", "6"))
    self.s1__box_4.setItemText(3, _translate("Form", "5"))
    self.s1__lb_5.setText(_translate("Form", "校验位:"))
    self.s1__box_5.setItemText(0, _translate("Form", "N"))
    self.open_button.setText(_translate("Form", "打开串口"))
    self.close_button.setText(_translate("Form", "关闭串口"))
    self.s1__lb_6.setText(_translate("Form", "停止位:"))
    self.s1__box_6.setItemText(0, _translate("Form", "1"))
    self.verticalGroupBox.setTitle(_translate("Form", "接受区"))
    self.verticalGroupBox_2.setTitle(_translate("Form", "发送区"))
    self.s3__send_text.setHtml(_translate("Form", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'SimSun\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">123456</p></body></html>"))
    self.s3__send_button.setText(_translate("Form", "发送"))
    self.s3__clear_button.setText(_translate("Form", "清除"))
    self.formGroupBox1.setTitle(_translate("Form", "串口状态"))
    self.label.setText(_translate("Form", "已接收:"))
    self.label_2.setText(_translate("Form", "已发送:"))
    self.hex_send.setText(_translate("Form", "Hex发送"))
    self.hex_receive.setText(_translate("Form", "Hex接收"))
    self.s2__clear_button.setText(_translate("Form", "清除"))
    self.timer_send_cb.setText(_translate("Form", "定时发送"))
    self.lineEdit_3.setText(_translate("Form", "1000"))
    self.dw.setText(_translate("Form", "ms/次"))

以上这篇使用Python3+PyQT5+Pyserial 实现简单的串口工具方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python实现Tab自动补全和历史命令管理的方法
Mar 12 Python
详解Python pygame安装过程笔记
Jun 05 Python
浅谈使用Python变量时要避免的3个错误
Oct 30 Python
python实现录音小程序
Oct 26 Python
linux查找当前python解释器的位置方法
Feb 20 Python
python hough变换检测直线的实现方法
Jul 12 Python
python求加权平均值的实例(附纯python写法)
Aug 22 Python
简单易懂Pytorch实战实例VGG深度网络
Aug 27 Python
使用 Python 处理3万多条数据只要几秒钟
Jan 19 Python
Pycharm生成可执行文件.exe的实现方法
Jun 02 Python
使用pandas读取表格数据并进行单行数据拼接的详细教程
Mar 03 Python
python实现进度条的多种实现
Apr 29 Python
PyQt5内嵌浏览器注入JavaScript脚本实现自动化操作的代码实例
Feb 13 #Python
Python实现Event回调机制的方法
Feb 13 #Python
Python socket实现多对多全双工通信的方法
Feb 13 #Python
对python文件读写的缓冲行为详解
Feb 13 #Python
python单线程文件传输的实例(C/S)
Feb 13 #Python
Python 实现文件打包、上传与校验的方法
Feb 13 #Python
使用python3构建文件传输的方法
Feb 13 #Python
You might like
PHP计算一年多少个星期和每周的开始和结束日期
2014/07/01 PHP
PHP实现的简易版图片相似度比较
2015/01/07 PHP
PHP基于SimpleXML生成和解析xml的方法示例
2017/07/17 PHP
php-beanstalkd消息队列类实例分享
2017/07/19 PHP
setTimeout与setInterval在不同浏览器下的差异
2010/01/24 Javascript
jquery判断小数点两位和自动删除小数两位后的数字
2014/03/19 Javascript
JS数组(Array)处理函数整理
2014/12/07 Javascript
详解JavaScript ES6中的Generator
2015/07/28 Javascript
CKEditor无法验证的解决方案(js验证+jQuery Validate验证)
2016/05/09 Javascript
jquery.qtip提示信息插件用法简单实例
2016/06/17 Javascript
JavaScript中关于for循环删除数组元素内容时出现的问题
2016/11/21 Javascript
jQuery模拟窗口抖动效果
2017/03/15 Javascript
javascript实现延时显示提示框效果
2017/06/01 Javascript
js禁止浏览器页面后退功能的实例(推荐)
2017/09/01 Javascript
详解Js中的模块化是如何实现的
2017/10/18 Javascript
浅谈 Vue 项目优化的方法
2017/12/16 Javascript
Vue与Node.js通过socket.io通信的示例代码
2018/07/25 Javascript
详解key在Vue列表渲染时究竟起到了什么作用
2019/04/20 Javascript
vue 实现特定条件下绑定事件
2019/11/09 Javascript
vue cli3.0打包上线静态资源找不到路径的解决操作
2020/08/03 Javascript
使用Python编写类UNIX系统的命令行工具的教程
2015/04/15 Python
python字典排序实例详解
2015/05/20 Python
Flask框架的学习指南之用户登录管理
2016/11/20 Python
python使用turtle库绘制时钟
2020/03/25 Python
keras模型保存为tensorflow的二进制模型方式
2020/05/25 Python
python 实现控制鼠标键盘
2020/11/27 Python
使用jTopo给Html5 Canva中绘制的元素添加鼠标事件
2014/05/15 HTML / CSS
html5 制作地图当前定位箭头的方法示例
2020/01/10 HTML / CSS
英国打印机墨水和碳粉商店:Printerinks
2017/06/30 全球购物
eHarmony英国:全球领先的认真恋爱约会平台之一
2020/11/16 全球购物
机械系大学毕业生推荐信
2013/11/27 职场文书
网络程序员自荐信
2014/01/25 职场文书
自考毕业自我鉴定
2014/03/18 职场文书
二人合伙经营协议书
2014/09/13 职场文书
2014小学数学教师个人工作总结
2014/12/18 职场文书
社区环境卫生倡议书
2015/04/29 职场文书