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