PowershellでExcelファイルをPDFに変換

Excelがインストールされていないと動きません

  1. それぞれ「xlsx2pdf.bat」「xlsx2pdf.ps1」をファイルに保存
  2. xlsxファイルをxlsx2pdf.batにドラッグ&ドロップするとpdfファイルが作成されます

xlsx2pdf.bat

powershell -NoProfile -ExecutionPolicy Unrestricted .\xlsx2pdf.ps1 %1

xlsx2pdf.ps1

if ( $args -eq $null ) {
    Write-Error '引数がありません'
}

if (Test-Path $args[0]) {
    $excel = New-Object -ComObject Excel.Application
    $excel.Visible = $false

    # 拡張子変更
    $newpdf = $args[0] -replace '\.xlsx$', '.pdf'


    try {
        $book = $excel.Workbooks.Open($args[0])

        # PDF
        $book.ExportAsFixedFormat([Microsoft.Office.Interop.Excel.XlFixedFormatType]::xlTypePDF, $newpdf)

        $book.Close($false)

    }
    catch {
        Write-Error 'エラーが発生しました'
    }
    finally {
        $excel.Quit()
        $excel = $null
        [GC]::Collect()
    }

}
else {
    Write-Error 'ファイルが見つかりません'
}

docs.microsoft.com

暑さ指数(WBGT)予測値を可視化

fukuno.jig.jp

www.wbgt.env.go.jp

import datetime

import pandas as pd
import matplotlib.pyplot as plt

point = 73076

df_tmp = pd.read_csv(f"https://www.wbgt.env.go.jp/prev15WG/dl/yohou_{point}.csv").T

dt_now = datetime.datetime.strptime(df_tmp.iat[1, 0], "%Y/%m/%d %H:%M")

df = df_tmp.iloc[2:].copy()

df.rename(columns={0: "WBGT"}, inplace=True)

df.index = df.index.astype(str).map(
    lambda s: pd.to_datetime(s[:8]) + pd.Timedelta(hours=int(s[8:]))
)

df["WBGT"] = df["WBGT"] / 10
df["状況"] = pd.cut(
    df["WBGT"], [0, 21, 25, 28, 31, 50], labels=["ほぼ安全", "注意", "警戒", "厳重警戒", "危険"]
)

df

ax = df.plot(grid=True, figsize=(10, 5))

ax.set_ylim(10, 40)

# 水平
ax.axhline(y=31, linestyle="--", color="red", linewidth=1, label="危険")
ax.axhline(y=28, linestyle="--", color="orange", linewidth=1, label="厳重警戒")
ax.axhline(y=25, linestyle="--", color="yellow", linewidth=1, label="警戒")
ax.axhline(y=21, linestyle="--", color="cyan", linewidth=1, label="注意")

# グラフを保存
plt.savefig("wbgt.png", dpi=200, bbox_inches="tight")
plt.show()

csv-table タグ

fukuno.jig.jp

これだとスクレイピングが簡単でいいな

import io

import requests
from bs4 import BeautifulSoup
import pandas as pd

url = "https://code4sabae.github.io/csv-table/"

r = requests.get(url)
r.raise_for_status()

soup = BeautifulSoup(r.content, "html.parser")
txt = soup.find("csv-table").get_text(strip=True)

df = pd.read_csv(io.StringIO(txt), index_col=0)
df

PowershellでExcelのアクティブシートをCSV(UTF-8)で保存

Excelがインストールされていないと動きません

  1. それぞれ「xlsx2csv.bat」「xlsx2csv.ps1」をファイルに保存
  2. xlsxファイルをxlsx2csv.batにドラッグ&ドロップするとcsvファイルが作成されます

xlsx2csv.bat

powershell -NoProfile -ExecutionPolicy Unrestricted .\xlsx2csv.ps1 %1

xlsx2csv.ps1

if ( $args -eq $null ) {
    Write-Error '引数がありません'
}

if (Test-Path $args[0]) {
    $excel = New-Object -ComObject Excel.Application
    $excel.Visible = $false

    # 拡張子変更
    $newcsv = $args[0] -replace '\.xlsx$', '.csv'


    try {
        $book = $excel.Workbooks.Open($args[0])

        # UTF8 CSV
        $book.SaveAs($newcsv, 62)
        $book.Close($false)

    }
    catch {
        Write-Error 'エラーが発生しました'
    }
    finally {
        $excel.Quit()
        $excel = $null
        [GC]::Collect()
    }

}
else {
    Write-Error 'ファイルが見つかりません'
}

山梨県の患者情報をスクレイピング

data.jsonまで作成

github.com

import copy
import datetime
import json
import pathlib
import re

import jaconv
import requests
from bs4 import BeautifulSoup


def get_title(tag):
    if tag.name == "h2":
        if tag.get_text(strip=True) == "新型コロナウイルス感染症の県内における発生状況":
            return True

    return False


r = requests.get(
    "https://www.pref.yamanashi.jp/koucho/coronavirus/info_coronavirus_prevention.html"
)
r.raise_for_status()
soup = BeautifulSoup(r.content, "html.parser")

h2 = soup.find(get_title)

data = []
s = ""

# 下向きに同レベルのタグを抽出

for tag in h2.find_next_siblings():
    if tag.name == "h4":
        data.append(jaconv.z2h(s.rstrip(), kana=False, digit=True, ascii=True))
        s = ""
    elif tag.name == "h2":
        data.append(jaconv.z2h(s.rstrip(), kana=False, digit=True, ascii=True))
        break

    s += tag.get_text(strip=True) + "\n"

data

JST = datetime.timezone(datetime.timedelta(hours=+9))

# 和暦から西暦のdateに変換
def wareki2date(s):

    m = re.match(r"令和(\d{1,2})年(\d{1,2})月(\d{1,2})日", s)

    year, month, day = map(int, m.groups())

    year += 2018

    result = datetime.datetime(year, month, day, tzinfo=JST)

    return result


result = []

for d in data[1:]:

    # m = re.match("^.+$", d, re.MULTILINE)
    m = re.match(r"県内\d{1,3}例目", d)

    if m:

        temp = {"No": m.group(0)}

        for i in re.finditer(r"(発生判明日|年代|性別|居住地):(.+)$", d, re.MULTILINE):
            temp[i.group(1)] = i.group(2)

            if i.group(1) == "居住地":

                t = copy.deepcopy(temp)

                t["リリース日"] = wareki2date(t["発生判明日"]).isoformat()
                del t["発生判明日"]
                t["退院"] = None

                result.append(t)

DATA_DIR = "data"

p = pathlib.Path(DATA_DIR, "data.json")
p.parent.mkdir(parents=True, exist_ok=True)

with p.open(mode="w", encoding="utf-8") as fw:
    json.dump(result[::-1], fw, ensure_ascii=False, indent=4)

imabari.hateblo.jp