Skip to content

Instantly share code, notes, and snippets.

@mnzk
Last active July 2, 2020 09:15
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mnzk/7840302 to your computer and use it in GitHub Desktop.
Save mnzk/7840302 to your computer and use it in GitHub Desktop.
PowerShell (V3) と iTextSharpで年賀状宛名印刷用PDFを作成
Set-Alias new New-Object
Set-Alias aps New-ApplyContext
Set-Alias use New-DisposeOnLeaveContext
# iTextSharp アセンブリロード
[System.Reflection.Assembly]::LoadFile | aps {
ls S:\libs\itextsharp-all-5.4.4\*.dll
} > $null
function first ([ScriptBlock]$Body) {
$input | select -First 1 | % { & $Body }
}
filter this ([ScriptBlock]$Body){
[void](& $Body)
$_
}
# 構造体のクローン作成
filter cloneStruct {
$it = $_
$it
}
# Drawing.RectangleF から iTextSharpのRectangleへ変換
# 座標系も変換します。
function ConvertTo-iRectangle([float]$PageHeight, [System.Drawing.RectangleF]$rectangle) {
$x0 = $rectangle.Left
$y0 = $PageHeight - $rectangle.Bottom
$x1 = $rectangle.Right
$y1 = $PageHeight - $rectangle.Top
new iTextSharp.text.Rectangle $x0,$y0,$x1,$y1
}
# フォントオブジェクト作成
function New-Font ([string]$font, [int]$size, [string]$direction="H"){
[iTextSharp.text.pdf.BaseFont]::"IDENTITY_$direction" `
| first { [iTextSharp.text.pdf.BaseFont]::CreateFont($font, $_, $true) } `
| first { new iTextSharp.text.Font $_, $size }
}
# 背景画像オブジェクト作成
function New-BgImage([string]$path, [int]$Width, [int]$Height) {
new System.Uri $path `
| first { [iTextSharp.text.Image]::GetInstance($_) } `
| this {
$_.Alignment = [iTextSharp.text.Image]::UNDERLYING
$_.ScaleToFit($Width, $Height)
}
}
# 縦書きテキスト描画
function Write-VirtialTextArea {
param (
[iTextSharp.text.DocWriter]$writer,
[iTextSharp.text.Font]$font,
[iTextSharp.text.Rectangle]$rect,
[string]$text
)
$x = $rect.Right - $font.Size / 2
$y = $rect.Top
$h = $rect.Height
$lines = 12
$leading = $font.Size
new iTextSharp.text.pdf.VerticalText $writer.DirectContent `
| this{
$_.SetVerticalLayout($x, $y, $h, $lines, $leading)
$_.Alignment = [iTextSharp.text.Element]::ALIGN_BASELINE
$_.AddText | aps { new iTextSharp.text.Chunk $text, $font }
$_.Go()
}
}
# PDF生成
function New-Pdf([PSObject]$param) {
use($ofs = new System.IO.FileStream($param.pdfPath ,[System.IO.FileMode]::OpenOrCreate)){
use($doc = new iTextSharp.text.Document([iTextSharp.text.PageSize]::POSTCARD),0,0,0,0){
$writer = [iTextSharp.text.pdf.PdfWriter]::GetInstance($doc, $ofs)
$doc.Open()
$pageW = $doc.PageSize.Width
$pageH = $doc.PageSize.Height
# バックグラウンドイメージ
$doc.Add | aps {
New-BgImage $param.backgroundImagePath $pageW $pageH
}
#
# 描画矩形領域作成
#
function irect ($pos, $size){
new System.Drawing.RectangleF $pos,$size `
| first { ConvertTo-iRectangle $pageH $_ }
}
#宛先住所エリア
$toAddrSize = new System.Drawing.SizeF ($pageW/3), ($pageH - 60*2)
$toAddrLocation = new System.Drawing.PointF ($pageW - $pageW/3 -20),60
$toAddrRect = irect $toAddrLocation $toAddrSize
#宛名エリア
$toNameSize = $toAddrSize
$toNameLocation = $toAddrLocation | cloneStruct `
| this {$_.X -= $toAddrSize.Width }
$toNameRect = irect $toNameLocation $toNameSize
#送り主住所エリア
$fromAddrSize = $toNameSize | cloneStruct `
| this { $_.Width *=0.4; $_.Height -= 100 }
$fromAddrLocation = $toNameLocation | cloneStruct `
| this { $_.X -= $toNameSize.Width*0.4; $_.Y += 95 }
$fromAddrRect = irect $fromAddrLocation $fromAddrSize
#送り主名エリア
$fromNameSize = $fromAddrSize | cloneStruct
$fromNameLocation = $fromAddrLocation | cloneStruct `
| this { $_.X -= $fromAddrSize.Width }
$fromNameRect = irect $fromNameLocation $fromNameSize
#
# 縦書きテキスト挿入
#
function write_vtext ($fontSize, $rect, $txt) {
New-Font "C:\Windows\Fonts\HGRGY.TTC,0" $FontSize "V" `
| first { Write-VirtialTextArea $writer $_ $rect $txt }
}
write_vtext 28 $toAddrRect $param.toAddr
write_vtext 34 $toNameRect $param.toName
write_vtext 18 $fromAddrRect $param.fromAddr
write_vtext 20 $fromNameRect $param.fromName
#
# 郵便番号
#
function write_zip ($fontSize, $rect, $txt) {
New-Font "C:\Windows\Fonts\msgothic.ttc,0" $fontSize "V" `
| first { Write-VirtialTextArea $writer $_ $rect $txt }
}
# 宛先郵便番号
$toZipSize = new System.Drawing.SizeF 14,16
$toZipLocation = new System.Drawing.PointF ($pageW-150),32
$param.toZip.ToCharArray() | foreach {
$toZipRect = irect $toZipLocation $toZipSize
write_zip 16 $toZipRect $_
$toZipLocation.X += 20
}
# 送り主郵便番号
$fromZipSize = new System.Drawing.SizeF 10,10
$fromZipLocation = new System.Drawing.PointF 22, ($pageH-68)
$param.fromZip.ToCharArray() | foreach {
$fromZipRect = irect $fromZipLocation $fromZipSize
write_zip 16 $fromZipRect $_
$fromZipLocation.X += 12
}
# 矩形色分け(確認用)
if($false){
$doc.Add | aps {
$toAddrRect | this { $_.BackgroundColor = [iTextSharp.text.BaseColor]::LIGHT_GRAY }
$toNameRect | this { $_.BackgroundColor = [iTextSharp.text.BaseColor]::YELLOW }
$fromAddrRect | this { $_.BackgroundColor = [iTextSharp.text.BaseColor]::LIGHT_GRAY }
$fromNameRect | this { $_.BackgroundColor = [iTextSharp.text.BaseColor]::YELLOW }
}
}
}}
}
# Run Main
try{
$param = [PSCustomObject]@{
backgroundImagePath = "C:\Dropbox\images2\nenga01.JPG"
toZip = "1234567"
toAddr = "神奈川県横須賀市 浦賀船渠一ノ二三"
toName = "涼風 五十鈴 様"
fromZip = "9998080"
fromAddr = "海軍佐世保市鎮守府 九九九"
fromName = " 阿賀野 由良"
pdfPath = "C:\temp\out_{0:yyyyMMddhhmmss}.pdf" -f (Get-Date)
}
New-Pdf $param > $null
. $param.pdfPath
}catch{
$Error[0]
break
}
<#
# 個人的に使ってるモジュール (抜粋)
#>
filter New-ApplyContext([ScriptBlock] $Body, [Switch] $PassResult){
$private:It = $_
if($PassResult){
$Body.Invoke() | % { $It.Invoke($_) }
}else{
$Body.Invoke() | % { $It.Invoke($_) } > $null
$It
}
}
function New-OnLeaveContext ([ScriptBlock] $Body, [ScriptBlock] $OnLeave){
try {
& $Body
}finally{
& $OnLeave
}
}
function New-DisposeOnLeaveContext ([System.IDisposable] $it, [ScriptBlock] $Body){
New-OnLeaveContext $Body {
if( $it ){ $it.Dispose() }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment