示例#1
0
def printable_doc(records_list, explicit_template):
    '''Generates a Word .docx file with one page for each record. Returns
    a Python docx Document object.'''

    num_pages = len(records_list)
    if num_pages < 1:
        return None
    template = explicit_template or normal_template()
    if not readable(template):
        raise InternalError('Cannot find a template file for printing.')
    date_time_stamps = current_date_and_time()

    # I tried appending directly to the docx and DocxTemplate objects, but
    # the results caused Word to complain that the file was corrupted.  The
    # algorithm below writes out a separate file for each record, then in a
    # subsequent loop, uses docxcompose to combine individual docx Document
    # objects for each file into one overall docx.

    files_list = []
    for index, record in enumerate(records_list):
        tmpfile = tempfile.TemporaryFile()
        doc = DocxTemplate(template)
        values = vars(records_list[index])
        values = {k: sanitized_string(v) for k, v in values.items()}
        values.update(date_time_stamps)
        doc.render(values)
        if index < (num_pages - 1):
            doc.add_page_break()
        doc.save(tmpfile)
        files_list.append(tmpfile)

    if len(files_list) < 2:
        return doc
    else:
        # The only way I found to create a viable single .docx file containing
        # multiple pages is to create separate docx Document objects out of
        # separate actual files (rather than trying to do it all in memory).
        composer = Composer(Document(files_list[0]))
        for page in files_list[1:]:
            composer.append(Document(page))
        return composer
示例#2
0
def dowork(filepath):
    allfiles = os.listdir(filepath)
    # 遍历该文件夹下的所有文件夹
    for file in allfiles:
        tem_path = os.path.join(filepath, file)
        # print(file == '三改一拆')
        # 判断该文件夹类型
        if file == '三改一拆':
            print(file)
            # 遍历得到所有年份目录
            for year_path in getdir(tem_path):
                print('获取年份目录 :' + year_path)
                docname = year_path + '年' + file + '台账' + '.docx'
                document = Document()
                target_composer = Composer(document)
                # 遍历年份目录得到所有月份目录
                for month_path in getdir(
                        os.path.join(filepath, file, year_path)):
                    print('获取月份目录 :' + month_path)
                    # 遍历所有月份目录,得到每月台账资料
                    for mc_path in getdir(
                            os.path.join(filepath, file, year_path,
                                         month_path)):
                        print('获取每月台账资料 :' + mc_path)
                        piclist = []
                        txtlist = []
                        for mc_file in os.listdir(
                                os.path.join(filepath, file, year_path,
                                             month_path, mc_path)):
                            print('获取每项台账资料文件 :' + mc_file)
                            if os.path.splitext(mc_file)[1] == '.txt':
                                txtlist.append(mc_file)
                            else:
                                piclist.append(
                                    os.path.join(filepath, file, year_path,
                                                 month_path, mc_path, mc_file))
                        if txtlist.__len__() > 1:
                            print('there are more than one txt file in ' +
                                  os.path.join(filepath, file, year_path,
                                               month_path, mc_path))
                        else:
                            tem_docx = DocxTemplate("template1.docx")
                            result_content_dict = {}
                            count = 0
                            while count < piclist.__len__():
                                image = InlineImage(tem_docx,
                                                    piclist[count],
                                                    width=Cm(7),
                                                    height=Cm(5))
                                result_content_dict["pic" + str(count)] = image
                                count += 1
                            for line in open(
                                    os.path.join(filepath, file, year_path,
                                                 month_path, mc_path,
                                                 txtlist[0]),
                                    "r",
                                    encoding="utf-8"):  # 设置文件对象并读取每一行文件
                                line = line.strip("\n")
                                data_list = line.split("#", 1)
                                if len(data_list):
                                    result_content_dict[
                                        data_list[0]] = data_list[1]
                            print(result_content_dict)
                            tem_docx.render(result_content_dict)
                            tem_docx.add_page_break()
                            target_composer.append(tem_docx)
                target_composer.save(
                    os.path.join(filepath, file, year_path) + "\\" + docname)
        elif file == '安全生产':
            print(file)
        else:
            print("无此类型台账模板:" + file)
class MainWindow(QtGui.QDialog, Ui_MainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        Ui_MainWindow.__init__(self)
        self.setupUi(self)
        self.errorPopup = MyPopup()

        # ---------------------------------------------------#
        # Local Variables
        # ---------------------------------------------------#
        # Create instance of Document.docx file
        self.filePath = ""
        self.userName = ""
        self.dateNow = datetime.datetime.now().date().strftime("%m-%d-%Y")
        self.projectName = ""
        self.document = DocxTemplate(cwd + "/default.docx")
        self.tableRowCount = 0

        # ---------------------------------------------------#
        # file name Variables -- add to list if additional
        #                       files are parsed in future
        # ---------------------------------------------------#
        self.fsum = ""
        self.fsum_erc = ""
        self.fcls = ""
        self.flog = ""
        self.fascii = ""
        self.fpictures = []

        # ---------------------------------------------------#
        # User Interface Property changes
        # ---------------------------------------------------#
        self.date.setText("Date: " + self.dateNow)

        # ---------------------------------------------------#
        # Call appropriate function on user actions
        # ---------------------------------------------------#
        self.okButton.clicked.connect(self.systemHandler)
        self.toolButton.clicked.connect(self.openExplorer)
        self.cancelButton.clicked.connect(self.closeApplication)

    # ----------------------------------------------------------------------------#
    #
    # Function Name: closeApplication()
    # Description: Called whenever cancel button is clicked by user. The
    #              application will close
    # Last Edited: 11/05/2016
    # Last Edited By: Jonathan Wesner
    # Last Changes Made: ...
    #
    # ----------------------------------------------------------------------------#

    def closeApplication(self):
        sys.exit(app.exec_())

    def openExplorer(self):
        fileDirectory = QtGui.QFileDialog.getExistingDirectory(
            self, "Select Directory")
        self.fileInput.setText(fileDirectory)

    def systemHandler(self):
        # ------------------------------------------------------------------------#
        # Handle file path error checking
        # ------------------------------------------------------------------------#
        self.filePath = str(self.fileInput.text())
        # Check that file path is valid
        if not os.path.exists(os.path.dirname(self.filePath)):
            self.displayError("File path provided not found.")
            return

        # ------------------------------------------------------------------------#
        # Handle user Name and Project Name and check that user has not left
        # blank.
        # ------------------------------------------------------------------------#
        self.userName = str(self.userNameEdit.text())
        self.projectName = str(self.projectNameEdit.text())
        if (self.userName is "") or (self.projectName is ""):
            self.displayError(
                "Please fill all fields including User Name and Project Name.")
            return

        # ------------------------------------------------------------------------#
        # Set title information and styling of Word Document here
        # ------------------------------------------------------------------------#
        style = self.document.styles['Normal']
        font = style.font
        font.name = 'Calibri'
        font.size = Pt(10)
        self.printToDocument(
            'Project Name: ' + self.projectName + '\n' + 'Tape-out Date: ' +
            str(self.dateNow) + '\n' + 'Preparer: ' + self.userName + '\n\n',
            True)

        # ------------------------------------------------------------------------#
        # Add Title Table
        #   table.cell(Row,Column) --- reference
        # ------------------------------------------------------------------------#
        self.tableRowCount = 0
        self.table = self.document.add_table(rows=0, cols=4)
        self.table.style = 'Light Shading'
        self.fillTable('File name', 'Description', 'File size (bytes)',
                       'Date/Time')
        # parse files and fill table
        self.getFileNames()
        self.document.add_page_break()

        # ------------------------------------------------------------------------#
        # Error check all files are present before continuing
        # ------------------------------------------------------------------------#
        if self.fsum == "":
            self.displayError(
                "No .sum file exists. Please include file in folder before continuing."
            )
            return
        if self.fsum_erc == "":
            self.displayError(
                "No .sum_erc file exists. Please include file in folder before continuing."
            )
            return
        if self.fcls == "":
            self.displayError(
                "No .rep.cls file exists. Please include file in folder before continuing."
            )
            return
        if self.fascii == "":
            self.displayError(
                "No .drc_errors.ascii file exists. Please include file in folder before continuing."
            )
            return
        if self.flog == "":
            self.displayError(
                "No .sum_erc file exists. Please include file in folder before continuing."
            )
            return

        # ------------------------------------------------------------------------#
        #   Order of Looking for files -- add to list as needed
        #       1)  .sum file
        #       2)  .ascii file (used to output errors of .sum file)
        #       3)  .cls file
        #       4)  .sum_erc
        #       5)  .log
        #       6)  .png or jpg (add pictures last)
        # ------------------------------------------------------------------------#
        collectErrors = ""
        # first argument of searchSumFile() takes in file name, second argument
        # allows for the collection of the summary section of the file
        self.printToDocument('DRC:', True)
        # Order File look up #1
        collectErrors = self.searchSumFile(self.fsum, False)

        # Order File look up #2
        self.printToDocument("DRC Errors:", True)
        self.sumFileErrors(collectErrors, self.fascii)

        # Order File look up #3
        self.printToDocument("LVS:", True)
        self.searchClsFile(self.fcls)

        # Order File look up #4
        collectErrors = ""
        self.printToDocument("ERC:", True)
        collectErrors = self.searchSumFile(self.fsum_erc, True)

        # Order File look up #5
        self.printToDocument("ERC Errors:", True)
        self.sumErcFileErrors(collectErrors, self.flog)

        # Add pictures here...order file look up #6
        self.printToDocument("Images:", True)
        if self.fpictures is not None:
            for img in self.fpictures:
                self.document.add_picture(img,
                                          width=Inches(3),
                                          height=Inches(3))

        # Save document
        self.document.save(self.filePath + '/summary.docx')

        # Message to user that file is done
        self.displayError(
            "File is Complete! File saved in folder where other files were specified.",
            "ATTENTION!")
        self.fileInput.setText("")
        self.userNameEdit.setText("")
        self.projectNameEdit.setText("")

    # ----------------------------------------------------------------------------#
    #
    # Function Name: getFileNames()
    # Description: This function takes care of grabing the file names needed to be
    #              opened. It uses the filePath variable to look for the files.
    #              Current files being read in are in this order...
    #                   1)  .sum file
    #                   2)  .ascii file (used to output errors of .sum file)
    #                   3)  .cls file
    #                   4)  .sum_erc file
    #                   5)  .log file
    #                   6)  .png or jpg(add pictures last)
    # Last Edited: 11/05/2016
    # Last Edited By: Jonathan Wesner
    # Last Changes Made: ...
    #
    # ----------------------------------------------------------------------------#

    def getFileNames(self):
        files = os.walk(self.filePath, topdown=False)
        for fileName in os.listdir(self.filePath):
            # --------------------------------------------------------------------#
            # get all files in folder and print out info to a table
            # --------------------------------------------------------------------#
            f = os.path.join(self.filePath, fileName)
            fileStats = os.stat(f)
            fileSize = fileStats.st_size
            dateLastModified = fileStats.st_mtime
            timeFormatted = datetime.datetime.fromtimestamp(
                int(dateLastModified)).strftime('%Y-%m-%d %H:%M:%S')
            self.fillTable(fileName, "", fileSize, timeFormatted)
            # --------------------------------------------------------------------#
            # check what type fileName is and fill the variables
            # --------------------------------------------------------------------#
            if fileName.endswith(".sum_erc"):
                self.fsum_erc = os.path.join(self.filePath, fileName)
            elif fileName.endswith(".sum"):
                self.fsum = os.path.join(self.filePath, fileName)
            elif fileName.endswith(".log"):
                if fileName.endswith(".streamout"):
                    return
                self.flog = os.path.join(self.filePath, fileName)
            elif fileName.endswith(".rep.cls"):
                self.fcls = os.path.join(self.filePath, fileName)
            elif fileName.endswith(".drc_errors.ascii"):
                self.fascii = os.path.join(self.filePath, fileName)
            else:
                if fileName.endswith(".png") or fileName.endswith(".jpg"):
                    self.fpictures.append(os.path.join(self.filePath,
                                                       fileName))

    # ----------------------------------------------------------------------------#
    #
    # Function Name: fillTable()
    # Description: This function takes in four data strings from each file
    #              that will be parsed and fills a table with the individual
    #              attributes of each file...
    # Last Edited: 10/29/2016
    # Last Edited By: Jonathan Wesner
    # Last Changes Made: ...
    #
    # ----------------------------------------------------------------------------#

    def fillTable(self, fileName, fileDescription, fileSize, fileDateTime):
        # Add Row
        self.table.add_row()

        # Define each column of the table before setting the values
        fName = self.table.cell(self.tableRowCount, 0)
        fDescription = self.table.cell(self.tableRowCount, 1)
        fSize = self.table.cell(self.tableRowCount, 2)
        fDateTime = self.table.cell(self.tableRowCount, 3)

        # fill each cell from passed in strings
        fName.text = fileName
        fDescription.text = fileDescription
        fSize.text = str(fileSize)
        fDateTime.text = fileDateTime

        # Add to tableRowCount
        self.tableRowCount = self.tableRowCount + 1

    # ----------------------------------------------------------------------------#
    #
    # Function Name: printToDocument()
    # Description: This function handles creating a new paragraph to the document.
    #              It takes in a string and will pass that string to the document.
    # Last Edited: 10/27/2016
    # Last Edited By: Jonathan Wesner
    # Last Changes Made: ...
    #
    # ----------------------------------------------------------------------------#

    def printToDocument(self, string, isBold=False):
        output = self.document.add_paragraph()
        output.add_run(string).bold = isBold

    # ----------------------------------------------------------------------------#
    #
    # Function Name: searchSumFile()
    # Description: This function handles searching the .sum file. It parses
    #              through the header of the file, and finds any errors under the
    #              RULECHECK section of the file. These errors are collected and
    #              passed to the sumFileErrors() function, which outputs the
    #              details of the errors from the drc_errors.ascii file.
    # Last Edited: 10/27/2016
    # Last Edited By: Jonathan Wesner
    # Last Changes Made: ...
    #
    # ----------------------------------------------------------------------------#

    def searchSumFile(self, fileToSearch, getSummary):

        sumFileHeader = ""
        sumFileSummary = ""
        sumHeaderDone = False
        summarySection = False
        sumCollectErrors = ""
        headerCount = 0

        # ------------------------------------------------------------------------#
        # Open .sum file and parse through to grab header/summary, and any errors
        # ------------------------------------------------------------------------#
        sumFile = open(fileToSearch, 'r')
        for line in sumFile:
            if (('------' in line) or
                ('******' in line)) and (sumHeaderDone is False):
                headerCount = headerCount + 1
                if headerCount > 1:
                    sumHeaderDone = True
                    sumFileHeader = sumFileHeader + line
            # Check for header finish
            if sumHeaderDone is False:
                sumFileHeader = sumFileHeader + line
            # Check for errors in file
            if sumHeaderDone:
                if ("RULECHECK " in line) and ("Total Result      0 (       0)"
                                               not in line):
                    sumCollectErrors = sumCollectErrors + " " + re.search(
                        'RULECHECK (.+?) ....', line).group(1) + " "
            # Parse through summary of file
            if getSummary:
                if "--- SUMMARY" in line:
                    summarySection = True
                if summarySection:
                    sumFileSummary = sumFileSummary + line

        # print header to document
        self.printToDocument(sumFileHeader)

        # print summary to header if needed
        if getSummary:
            self.printToDocument(sumFileSummary)

        # Close file
        sumFile.close()
        return sumCollectErrors

    # ----------------------------------------------------------------------------#
    #
    # Function Name: sumFileErrors()
    # Description: This function is called by searchSumFile() and outputs
    #              details about the particular errors found in the
    #              searchSumFile().
    # Last Edited: 10/27/2016
    # Last Edited By: Jonathan Wesner
    # Last Changes Made: ...
    #
    # ----------------------------------------------------------------------------#

    def sumFileErrors(self, errorsToSearch, errorFileToSearch):

        checkStatus = False
        sumErrors = ""
        errorFile = open(errorFileToSearch, 'r')
        for line in errorFile:

            # remove '\n' at end of line
            stripLine = line.rstrip()
            result = re.search(stripLine, errorsToSearch)
            if checkStatus is True:
                sumErrors = sumErrors + line
                if error in stripLine:
                    sumErrors = sumErrors + "\n"
                    checkStatus = False

            if result is not None:
                checkStatus = True
                error = stripLine
                sumErrors = sumErrors + line

        self.printToDocument(sumErrors)
        errorFile.close()

    # ----------------------------------------------------------------------------#
    #
    # Function Name: sumFileErrors()
    # Description: This function is called by searchSumFile() and outputs
    #              details about the particular errors found in the
    #              .sum_erc file
    # Last Edited: 10/29/2016
    # Last Edited By: Jonathan Wesner
    # Last Changes Made: ...
    #
    # ----------------------------------------------------------------------------#

    def sumErcFileErrors(self, errorsToSearch, errorFileToSearch):

        sumErrors = ""
        errorFile = open(errorFileToSearch, 'r')
        errorFound = False
        errorsToSearch = re.findall('ERC(.+?) ', errorsToSearch)
        for line in errorFile:

            # remove '\n' at end of line
            if errorFound:
                sumErrors = sumErrors + line
                if "}" in line:
                    errorFound = False
            else:
                for error in errorsToSearch:
                    if (('RULE ERC' + error + " {") in line):
                        sumErrors = sumErrors + line
                        errorFound = True
                        break

        self.printToDocument(sumErrors)
        errorFile.close()

    # ----------------------------------------------------------------------------#
    #
    # Function Name: searchClsFile()
    # Description: This function is searches for and prints out the header
    #              in the .cls file.
    # Last Edited: 10/27/2016
    # Last Edited By: Jonathan Wesner
    # Last Changes Made: ...
    #
    # ----------------------------------------------------------------------------#

    def searchClsFile(self, fileToSearch):

        clsHeaderDone = False
        clsFileHeader = ""
        headerCount = 0
        clsFile = open(fileToSearch, 'r')

        for line in clsFile:
            if ('###########' in line) and (clsHeaderDone == False):
                headerCount = headerCount + 1
                if headerCount > 1:
                    clsHeaderDone = True
                    clsFileHeader = clsFileHeader + line

            if clsHeaderDone == False:
                clsFileHeader = clsFileHeader + line

        self.printToDocument(clsFileHeader)
        clsFile.close()

    # #############################################################################
    #
    # Function Description: This function is called whenever an error message
    #                       needs to be displayed to the screen.
    # Last Edited: 11/12/2016
    # Last Edited By: Jonathan Wesner
    # Last Changes Made: ...
    #
    # #############################################################################

    def displayError(self, errorText, title="ERROR!"):
        self.errorPopup.errorMessage.setText(errorText)
        self.errorPopup.title.setText(title)
        # Freezes the Main Window till a response is made by the user for MyPopup()
        self.errorPopup.setWindowModality(QtCore.Qt.ApplicationModal)
        self.errorPopup.show()
示例#4
0
    elif tabl['V_INDICATOR'][i] == 1: # v
        temp = DocxTemplate(invoice_template_v)
    else: # default
        temp = DocxTemplate(invoice_template)

    ### grab data for temp doc
    if tabl['RP_INDICATOR'][i] == 1: # rp
        grab_data_mult(i)
        next(my_iter) #skip rp2
        next(my_iter) #skip rp3
    else: # default
        grab_data(i)

    # render the doc and add page break
    temp.render(data)
    temp.add_page_break()

    # if no email indicator, merge to paper invoice
    if tabl['EMAIL_IND'][i] == 0:
        ### append temp doc to master
        # check for DIRECTION
        if tabl['DIRECTION'][i].strip() == 'PP':
            # append doc to growing master composer pp doc
            composer_doc_pp.append(temp)
        else:
            # append doc to growing master composer gg doc
            composer_doc_gg.append(temp)
    else:
        # check for DIRECTION
        if tabl['DIRECTION'][i].strip() == 'PP':
            # pp path