前幾天弄了台北市分區的表格,發現橫向資料太多,需要改滿多的...,就改變一下,先做行政各區的天氣預報
會這樣決定是因為想先把小部份完成,看一下效果,再做個全台北市的天氣預報。
各區天氣預報要呈現項目
整理資料局部程式碼,這邊將需要的欄位(溫度、體感溫度...),都用一個list處理
dataDictList = []
locations = resJson["records"]["locations"][0]["location"]
for index, location in enumerate(locations):
weatherElements = location["weatherElement"]
temperatureDictList = [] # 溫度
aTemperatureDictList = [] # 體感溫度
pop6HDictList = [] # 降雨機率 6hr
wxDictList = [] # 天氣現象
ciDictList = [] # 舒適度
for weatherElement in weatherElements:
# 溫度
if weatherElement["elementName"] == "T":
timeDicts = weatherElement["time"]
for timeDict in timeDicts:
temperatureDictList.append({
"dataTime": timeDict["dataTime"],
"value": timeDict["elementValue"][0]["value"],
})
# 體感溫度
if weatherElement["elementName"] == "AT":
timeDicts = weatherElement["time"]
for timeDict in timeDicts:
aTemperatureDictList.append({
"dataTime": timeDict["dataTime"],
"value": timeDict["elementValue"][0]["value"],
})
# 降雨機率 百分比
if weatherElement["elementName"] == "PoP6h":
timeDicts = weatherElement["time"]
for timeDict in timeDicts:
pop6HDictList.append({
"startTime": timeDict["startTime"],
"endTime": timeDict["endTime"],
"value": timeDict["elementValue"][0]["value"],
})
# 天氣現象 Text
if weatherElement["elementName"] == "Wx":
timeDicts = weatherElement["time"]
for timeDict in timeDicts:
wxDictList.append({
"startTime": timeDict["startTime"],
"endTime": timeDict["endTime"],
"value": timeDict["elementValue"][0]["value"],
})
# 舒適度指數
if weatherElement["elementName"] == "CI":
timeDicts = weatherElement["time"]
for timeDict in timeDicts:
ciDictList.append({
"dataTime": timeDict["dataTime"],
"valueNum": timeDict["elementValue"][0]["value"],
"value": timeDict["elementValue"][1]["value"],
})
tempDict = {
"locationName": location["locationName"],
"temperatureDictList": temperatureDictList,
"aTemperatureDictList": aTemperatureDictList,
"pop6HDictList": pop6HDictList,
"wxDictList": wxDictList,
"ciDictList": ciDictList,
}
dataDictList.append(tempDict)
這邊字體有多定義了標題一、標題二,字體大小不一樣
以各行政區一頁,跑迴圈呼叫 表格func,專門寫各區的表格,因為降雨機率為六個小時,所以會用到合併欄位
('SPAN', (3, 1), (3, 2)), 後面參數是從哪裡到哪裡。
處理Pdf 局部程式碼
def getPDFTableDistrict(dataDict, showDateText):
tableStyle = TableStyle([
('ALIGN', (0, 0), (-1, -1), 'CENTER'),
('FONTNAME', (0, 0), (-1, -1), 'kaiu'),
('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
('GRID', (0, 0), (-1, -1), 0.5, colors.black),
('SPAN', (3, 1), (3, 2)),
('SPAN', (3, 3), (3, 4)),
('SPAN', (3, 5), (3, 6)),
('SPAN', (3, 7), (3, 8)),
])
# dataDict["locationName"]
headerList = [
showDateText,
Paragraph("溫度", style=styleNormalCustom),
Paragraph("體感溫度", style=styleNormalCustom),
Paragraph("降雨機率", style=styleNormalCustom),
Paragraph("天氣現象", style=styleNormalCustom),
Paragraph("舒適度", style=styleNormalCustom),
]
bodyList = [
["00:00"], ["03:00"], ["06:00"], ["09:00"],
["12:00"], ["15:00"], ["18:00"], ["21:00"]
]
def bodyGetIndex(dataTime):
hour = int(dataTime.split(" ")[1].split(":")[0])
bodyIndex = int(hour / 3)
return bodyIndex
for temperatureDict in dataDict["temperatureDictList"]:
dataTime = temperatureDict["dataTime"]
if showDateText in dataTime:
bodyIndex = bodyGetIndex(dataTime)
bodyList[bodyIndex].append(Paragraph(f"{temperatureDict['value']}℃", style=styleNormalCustom))
for aTemperatureDict in dataDict["aTemperatureDictList"]:
dataTime = aTemperatureDict["dataTime"]
if showDateText in dataTime:
bodyIndex = bodyGetIndex(dataTime)
bodyList[bodyIndex].append(Paragraph(f"{aTemperatureDict['value']}℃", style=styleNormalCustom))
for pop6HDict in dataDict["pop6HDictList"]:
startTime = pop6HDict["startTime"]
if showDateText in startTime:
bodyIndex = bodyGetIndex(startTime)
bodyList[bodyIndex].append(Paragraph(f"{pop6HDict['value']}%", style=styleNormalCustom))
# 這裡+1 是為了補合併欄位的空格
bodyList[bodyIndex + 1].append(Paragraph("", style=styleNormalCustom))
for wxDict in dataDict["wxDictList"]:
startTime = wxDict["startTime"]
if showDateText in startTime:
bodyIndex = bodyGetIndex(startTime)
bodyList[bodyIndex].append(Paragraph(wxDict["value"], style=styleNormalCustom))
for ciDict in dataDict["ciDictList"]:
dataTime = ciDict["dataTime"]
if showDateText in dataTime:
bodyIndex = bodyGetIndex(dataTime)
bodyList[bodyIndex].append(Paragraph(ciDict["value"], style=styleNormalCustom))
tableDataList = [
headerList,
*bodyList,
]
table = Table(tableDataList, style=tableStyle)
return table
# 一般字體
styleNormalCustom = ParagraphStyle(
'styleNormalCustom',
fontName='kaiu',
parent=styles["Normal"],
alignment=TA_CENTER,
)
styleNormalCustomHeader = ParagraphStyle(
'styleNormalCustom',
fontName='kaiu',
parent=styles["Normal"],
alignment=TA_CENTER,
fontSize=18
)
styleNormalCustomHeader2 = ParagraphStyle(
'styleNormalCustom',
fontName='kaiu',
parent=styles["Normal"],
alignment=TA_CENTER,
fontSize=16
)
pdfmetrics.registerFont(TTFont('kaiu', "font/kaiu.ttf"))
fileName = "example.pdf"
pdfTemplate = SimpleDocTemplate(fileName)
story = []
today = datetime.datetime.today().date()
showDate = today + datetime.timedelta(days=1)
todayDate = datetime.datetime.today().date()
tomorrow = todayDate + datetime.timedelta(days=1)
dayAfterTomorrow = tomorrow + datetime.timedelta(days=1)
tomorrowText = tomorrow.strftime('%Y-%m-%d')
dayAfterTomorrowText = dayAfterTomorrow.strftime('%Y-%m-%d')
# 以各行政區一頁,跑迴圈呼叫table
for dataDict in dataDictList:
story.append(Paragraph("未來鄉鎮天氣預報", style=styleNormalCustomHeader))
story.append(Spacer(1, 0.15 * inch)) # 給間距
story.append(Paragraph(dataDict["locationName"], style=styleNormalCustomHeader2))
story.append(Spacer(1, 0.15 * inch)) # 給間距
table = getPDFTableDistrict(dataDict, tomorrowText) # 先做明天
story.append(table)
story.append(PageBreak())
pdfTemplate.build(story)
結果圖 總共有12頁,隨便拿兩頁看一下,看起來還不錯,就清楚顯示所有資料欄位。
參考資料: