將昨天用到的台北市各區未來兩天的溫度,顯示在表格吧。
首先我會先整理資料,把需要的資料存成新的List,之後畫表格的時候會比較單純。
程式碼,只留各區的溫度。
authorization = "xx"
url = "https://opendata.cwb.gov.tw/api/v1/rest/datastore/F-D0047-061"
res = requests.get(url, {"Authorization": authorization})
resJson = res.json()
dataDictList = []
locations = resJson["records"]["locations"][0]["location"]
for location in locations:
temperatureDictList = []
weatherElements = location["weatherElement"]
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"],
})
tempDict = {
"locationName": location["locationName"],
"temperatureDictList": temperatureDictList
}
dataDictList.append(tempDict)
再來寫一個func 去抓明後天的資料,因為資料會含今天的,所以要用判斷日期,預期顯示結果是,第一排顯示各區名稱,由左至右,最左邊一行是時間,有 00, 03, 06, 09, 12, 15, 18, 21,每三個小時,這邊就全部顯示了,有點多就是了。
def getPDFTableDay(dataDictList, 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),
])
headerList = [showDateText]
bodyList = [
["00:00"], ["03:00"], ["06:00"], ["09:00"],
["12:00"], ["15:00"], ["18:00"], ["21:00"]
]
for dataDict in dataDictList:
headerList.append(dataDict["locationName"])
for temperatureDict in dataDict["temperatureDictList"]:
dataTime = temperatureDict["dataTime"]
if showDateText in dataTime:
hour = int(dataTime.split(" ")[1].split(":")[0])
bodyIndex = int(hour / 3)
bodyList[bodyIndex].append(
Paragraph(temperatureDict["value"], style=styleNormalCustom)
)
tableDataList = [
headerList,
*bodyList,
]
table = Table(tableDataList, style=tableStyle)
return table
styles = getSampleStyleSheet()
styleNormalCustom = ParagraphStyle(
'styleNormalCustom',
fontName='kaiu',
parent=styles["Normal"],
alignment=TA_CENTER,
)
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 = getPDFTableDay(dataDictList, tomorrowText)
story.append(table)
story.append(Spacer(1, 0.3 * inch))
# 畫後天的表格
table = getPDFTableDay(dataDictList, dayAfterTomorrowText)
story.append(table)
pdfTemplate.build(story)
結果圖,就可以看到明天27號比較冷,連中午都還在22度左右
後天28號,中午還有24、25度左右
程式應該可以寫得更好,或做好一點的處理及顯示。
參考資料:
大神 getSampleStyleSheet() 在那裡?
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
大神,請問要把整個table裡的中文都顯示要怎麼做?
因為我把story.append(table)改成story.append(Paragraph(table))會出現下面錯誤。
TypeError: Table.split() missing 1 required positional argument: 'availHeight'
謝謝
懂了,要先把table轉成list,然後在用for迴圈去附加上去。
謝謝
下面是問Chat GPT產生的程式,我發現用Canvas反而更容易處裡中文字型。
pdfmetrics.registerFont(TTFont('kaiu', r"C:\Windows\Fonts\kaiu.ttf"))
#创建PDF文档
pdf = canvas.Canvas("test_2tables_gpt1.pdf", pagesize=A4)
pdf.setFont("kaiu",14) #set font to support cht.
#将第一个表格添加到PDF页面上
table1.wrapOn(pdf, 0, 0)
table1.drawOn(pdf, 1*inch, 9*inch)
#添加一些间隔
pdf.drawCentredString(100,100,"間隔")
#将第二个表格添加到PDF页面上
table2.wrapOn(pdf, 0, 0)
table2.drawOn(pdf, 1*inch, 6*inch)
#保存PDF文件并关闭Canvas
pdf.save()
感謝分享
我還沒試過,改天來試試