我有一个使用ReportLab创建报告的python脚本,该脚本已经过测试并按预期工作,但有时我收到以下错误消息
TraceBack info:
File "C:\tools\LegionellaTool.py", line 605, in <module>
createReport(selectedCoolingTowers, Report_outputs_folder, dbo_COLGIS, openPDF)
Error Info:
..\Objects\moduleobject.c:50: bad argument to internal function
第605行是createReport(selectedCoolingTowers, Report_outputs_folder, dbo_COLGIS, openPDF)
createReport是...创建报告的功能。 我已经通过代码进行了调试,但我没有遇到任何错误,可能会出现错误,错误只会在某些情况下发生,而在其他情况下报告创建正常。
编辑===== createReport代码
def createReport(myReportTable, myReportFolder, M3Table, OpenPDF):
global Author
global TimeStamp
## myReportTable = gp.GetParameterAsText(0)
## myReportFolder = gp.GetParameterAsText(1)
## M3Table = gp.GetParameterAsText(2)
## OpenPDF = gp.GetParameterAsText(3)
Author = getpass.getuser() #gets OS user name
TimeStamp = str(datetime.datetime.now().hour) + ':' + str(datetime.datetime.now().minute) + ' on the ' + str(datetime.date.today().day) + '/' + str(datetime.date.today().month) + '/' + str(datetime.date.today().year)
#add time stamp to file name
myFile = myReportFolder + os.sep + 'CoolingTowersForInspection_' + str(datetime.datetime.now().hour) + '_' + str(datetime.datetime.now().minute) + '_' + str(datetime.date.today().day) + '_' + str(datetime.date.today().month) + '_' + str(datetime.date.today().year) + '.pdf'
c = reportlab.pdfgen.canvas.Canvas(myFile)
#creates sectors array
sectors = []
sectors.append('NW')
sectors.append('NE')
sectors.append('SW')
sectors.append('SE')
for sector in sectors:
#sector header
#framePage(c, 'Cooling Towers for Inspection - ' + sector + ' sector')
title = 'Cooling Towers for Inspection - ' + sector + ' sector'
c.setFont('Helvetica',20) #title font
c.drawString(reportlab.lib.units.inch, 10.5 * reportlab.lib.units.inch, title) #creates title
c.setFont('Helvetica',10) #header and footer font
#creates header
c.drawCentredString(4.135 * reportlab.lib.units.inch, 0.75 * reportlab.lib.units.inch,
'Report generated by ' + Author + ' at ' + TimeStamp + ' - Page %d' % c.getPageNumber())
#creates footer
c.drawCentredString(4.135 * reportlab.lib.units.inch, 11.00 * reportlab.lib.units.inch,
'Environmental Services')
#draw a border
c.setStrokeColorRGB(1,0,0)
c.setLineWidth(5)
c.line(0.8 * reportlab.lib.units.inch, reportlab.lib.units.inch, 0.8 * reportlab.lib.units.inch, 10.75 * reportlab.lib.units.inch)
#reset carefully afterwards
c.setLineWidth(1)
c.setStrokeColorRGB(0,0,0)
c.setFont('Helvetica', 10)
#gets towers in that sector
myTowers = arcpy.SearchCursor(myReportTable,"\"SECTOR\" = '" + sector + "'","","")
selTower = myTowers.next()
y = 730
if selTower is not None:
while selTower:
#insert page break when close to the end of the page
if y < 110:
c.showPage()
y = 730
framePage(c, 'Cooling Towers for Inspection - ' + sector + ' sector')
if selTower.TOWER_NAME <> None:
c.drawString(100, y, string.strip(selTower.TOWER_NAME))
else:
c.drawString(100, y, "na")
y = y - 12
if selTower.TOWER_ADDRESS <> None:
c.drawString(100, y, string.strip(selTower.TOWER_ADDRESS))
else:
c.drawString(100, y, "na")
y = y - 12
c.drawString(100, y, "Number of towers: " + str(int(selTower.NUMBER_OF_TOWERS)) + " ; M3 Code: " + selTower.UKEY + " ; Distance band: " + str(int(selTower.distance)) + " meters")
y = y - 12
inspectString = ""
if selTower.TOWER_RATING <> None:
inspectString = "Inspection rating: " + selTower.TOWER_RATING
else:
inspectString = "Inspection rating: na;"
if selTower.TOWER_LAST_INSPECTION <> None:
t = selTower.TOWER_LAST_INSPECTION
strLastInspection = t.strftime("%A, %d %b %Y")
inspectString = inspectString + " Last inspection: " + strLastInspection
#inspectString = inspectString + " Last inspection: " + selTower.TOWER_LAST_INSPECTION
else:
inspectString = inspectString + " Last inspection: na"
c.drawString(100, y, inspectString)
y = y - 12
c.drawString(100, y, "Contacts:")
y = y - 12
myTowerUKEY = selTower.UKEY
#gets contacts for that cooling tower
myTowerContacts = arcpy.SearchCursor(M3Table,"\"UKEY\" = '" + myTowerUKEY + "'","","")
selContact = myTowerContacts.next()
while selContact:
if y < 110:
c.showPage()
y = 730
framePage(c, 'Cooling Towers for Inspection - ' + sector + ' sector')
contact = ""
if selContact.TITLE <> None:
if string.strip(selContact.TITLE) <> "":
contact = string.strip(selContact.TITLE) + " "
if selContact.FIRSTNAME <> None:
contact = contact + selContact.FIRSTNAME + " "
if selContact.FAMILYNAME <> None:
contact = contact + selContact.FAMILYNAME + " "
if selContact.JOBTITLE <> None:
contact = contact + "(" + selContact.JOBTITLE + ") "
if selContact.TELW <> None:
contact = contact + selContact.TELW + "(work) "
if selContact.MOBILE <> None:
if string.strip(selContact.MOBILE) <> "":
contact = contact + string.strip(selContact.MOBILE) + "(mobile) "
if selContact.TELH <> None:
if string.strip(selContact.TELH) <> "":
contact = contact + string.strip(selContact.TELH) + "(home)"
contact = string.strip(contact)
c.drawString(100, y, contact)
y = y - 12
selContact = myTowerContacts.next()
y = y - 12
del myTowerContacts
selTower = myTowers.next()
else:
c.drawString(100, y, "no cooling towers for inspection in this sector")
c.showPage() #insert page break after each sector
del myTowers
c.save()
if OpenPDF == "true":
os.startfile(myFile)
#function that creates each page
def framePage(canvas, title):
canvas.setFont('Helvetica',20) #title font
canvas.drawString(reportlab.lib.units.inch, 10.5 * reportlab.lib.units.inch, title) #creates title
canvas.setFont('Helvetica',10) #header and footer font
#creates header
canvas.drawCentredString(4.135 * reportlab.lib.units.inch, 0.75 * reportlab.lib.units.inch,
'Report generated by ' + Author + ' at ' + TimeStamp + ' - Page %d' % canvas.getPageNumber())
#creates footer
canvas.drawCentredString(4.135 * reportlab.lib.units.inch, 11.00 * reportlab.lib.units.inch,
'Environmental Services')
#draw a border
canvas.setStrokeColorRGB(1,0,0)
canvas.setLineWidth(5)
canvas.line(0.8 * reportlab.lib.units.inch, reportlab.lib.units.inch, 0.8 * reportlab.lib.units.inch, 10.75 * reportlab.lib.units.inch)
#reset carefully afterwards
canvas.setLineWidth(1)
canvas.setStrokeColorRGB(0,0,0)
编辑编号2 *
完全追溯就在这里
Traceback (most recent call last):
File "C:\tools\LegionellaTool.py", line 613, in <module>
createReport(selectedCoolingTowers, Report_outputs_folder, dbo_COLGIS, openPDF)
File "C:\tools\LegionellaTool.py", line 120, in createReport
c.drawString(reportlab.lib.units.inch, 10.5 * reportlab.lib.units.inch, title) #creates title
File "c:\python26\arcgis10.0\lib\site-packages\reportlab\pdfgen\canvas.py", line 1481, in drawString
t.textLine(text)
File "c:\python26\arcgis10.0\lib\site-packages\reportlab\pdfgen\textobject.py", line 426, in textLine
self._code.append('%s T*' % self._formatText(text))
File "c:\python26\arcgis10.0\lib\site-packages\reportlab\pdfgen\textobject.py", line 393, in _formatText
for f, t in pdfmetrics.unicode2T1(text,[font]+font.substitutionFonts):
SystemError: ..\Objects\moduleobject.c:50: bad argument to internal function
<type 'exceptions.SystemExit'>: 1
谢谢
答案 0 :(得分:0)
根据我的经验,ReportLab的间歇性错误通常是由于在尝试渲染可能包含“奇怪”内容的文本时出现的问题,例如字符集的意外字符或空值。查看代码我没有发现任何明显会导致问题的内容,但您可能希望查看某些内容包含意外值的可能性。
特别是,我将查看处理selContact
的代码,看看它的任何属性是否意外为空,或者只是不是可能导致错误的字符串。
如果没有完整的堆栈跟踪,很难说出更具体的内容。
<强> ETA 强>
基于现在提供的堆栈跟踪,看起来问题必须是您正在尝试绘制的title
变量或者用于绘制字符串的字体。看看你的代码,我没有注意到任何问题,并且没有任何迹象表明代码中引发错误的部分间歇性问题。
答案 1 :(得分:0)
这条消息让我疯狂了过去几周,我终于想出了导致这个错误的两件事以及如何解决这些错误:
正如G Gordon Worley III建议的那样,如果您尝试使用不正确的元素构建报告,则可能会出现。
修复:查找哪个元素已损坏或在ArcGIS外部调试您的程序,您将收到更明确的错误消息。
如果您的Python安装有点混乱,可能会出现。对我来说发生的事情是我将ReportLab文件包含在与我的脚本相同的文件夹中,以便于分发。但我以前也在我的Python安装文件夹中安装了ReportLab。不知何故,这让ArcGIS感到困惑。
修复:删除Python ?? /(ArcGIS ??。?/)Lib / site-packages / reportlab文件夹,以便您的脚本只有一个库选项。
我希望这会对某人有所帮助。