전반적으로 나는 Esri 지오 데이터베이스에 저장된지도 및 이미지와 일부 표 형식의 데이터를 포함하는 PDF 보고서를 만들고 싶었습니다. 위의 방법과 시간 문제에 대한 정보 부족으로 Arcpy.Mapping을 사용하여 이미지를 포함하여지도 레이어 요소를 업데이트하고 레이아웃을 내 보냅니다.
도움이 될 예제와 스레드가 많기 때문에 MatplotLib을 사용하여 차트와 테이블을 추가로 생성했습니다. ArcGIS Desktop 및 Server와 함께 설치되어 클라이언트 용 타사 라이브러리를 설치하기위한 전제 조건을 피할 수 있습니다.
import matplotlib.pyplot as plt
import xlrd
import xlwt
import datetime
import os
import glob
import arcpy
import SSReport as REPORT
import numpy as NUM
from matplotlib.backends.backend_pdf import PdfPages as PDF
import matplotlib.pyplot as PLT
# get path for mxd template from location of script
filePath = os.path.dirname(os.path.abspath(__file__))
templatePath = os.path.join(filePath,"templates")
def TabletoPDF2(outdir, outputPDF):
tables = [os.path.join(outdir,'scratch.gdb', 'table1'),
os.path.join(outdir, 'scratch.gdb', 'table2')]
pp = PDF(outputPDF)
for table in tables:
# convert to format for creating charts.
ntab = arcpy.da.TableToNumPyArray(table, "*")
columns = [fld for fld in ntab.dtype.names if fld not in ["OBJECTID"]]
cell_text = []
for row in ntab.tolist():
cell_text.append(row[1:])
fig = PLT.figure(figsize=(8.2, 10.6))
# Create PIECHART (percent lengeth)
ax1 = PLT.subplot(211)
data = ntab["percent_len"].tolist()
vals = [x for x in data if x > 0.]
labels = ntab[columns[0]].tolist()
labels = [n for n, v in zip(labels, data) if v > 0]
ax1.pie(vals, autopct='%1.1f%%', shadow=True, startangle=90)
ax1.axis('equal')
ax1.legend(labels, loc='center right', fontsize=8, bbox_to_anchor=(1, 1))
# Create TABLE of values
ax2 = PLT.subplot(212)
the_table = PLT.table(cellText=cell_text, colLabels=columns, loc='center')
the_table.auto_set_font_size(True)
PLT.axis('off')
PLT.tight_layout()
#### Set Title ####
title = os.path.basename(table)
PLT.suptitle(title, fontsize=11, fontweight='bold')
pp.savefig(fig)
pp.close()
return outputPDF
def CreatePDFReport(sPath, outprofilegraph, sfroute_feat):
template_mxd_filename = os.path.join(templatePath,'Reportemplate.mxd')
layoutpdf_filename = os.path.join(sPath,'Layout.pdf')
tablepdf_filename = os.path.join(sPath,'TableReport.pdf')
finalpdf_filename = os.path.join(sPath,'Final Report.pdf')
#Create layout report (page1)
arcpy.AddMessage("Creating Layout...")
arcpy.AddMessage(template_mxd_filename)
mxd = arcpy.mapping.MapDocument(template_mxd_filename)
change_picture_element(mxd, outprofilegraph)
change_layer_source(mxd, sfroute_feat)
arcpy.mapping.ExportToPDF(mxd,layoutpdf_filename)
# Create Table Report(page2)
TablePDF = CreateTableReport(tablepdf_filename)
TablePDF = TabletoPDF2(sPath, tablepdf_filename)
#Create Final report (merge)
msg = ("Creating Output Report {}".format(finalpdf_filename))
arcpy.AddMessage(msg)
if os.path.exists(finalpdf_filename):
os.remove(finalpdf_filename)
pdfFinal = arcpy.mapping.PDFDocumentCreate(finalpdf_filename)
pdfFinal.appendPages(layoutpdf_filename)
pdfFinal.appendPages(TablePDF)
pdfFinal.saveAndClose()
os.remove(tablepdf_filename)
os.remove(layoutpdf_filename)
return finalpdf_filename
def change_layer_source(mxd, route_feat):
""" Update layer datasource and zoom to extent """
arcpy.AddMessage(route_feat)
replace_workspace_path, datasetname = os.path.split(route_feat)
df = arcpy.mapping.ListDataFrames(mxd)[0]
for lyr in arcpy.mapping.ListLayers(mxd, data_frame=df):
if lyr.name == 'RouteLayer':
lyr.replaceDataSource (replace_workspace_path, "None")
ext = lyr.getExtent()
df.extent = ext
# mxd.save()
def change_picture_element(mxd, outprofilegraph):
for elm in arcpy.mapping.ListLayoutElements(mxd, "PICTURE_ELEMENT"):
if elm.name == "elevprofile":
elm.sourceImage = outprofilegraph
# mxd.save()
if __name__ == '__main__':
folderPath = arcpy.GetParameterAsText(0)
inTable = arcpy.GetParameterAsText(1)
sfroute_feat = arcpy.GetParameterAsText(2)
finalReport = CreatePDFReport(folderPath, outprofilegraph, sfroute_feat)
# Set outputs
arcpy.SetParameterAsText(4, finalReport)
: 여기
은 샘플입니다