pdfファイルをマージするアプリケーション(2)

pdfファイルの取り扱いは、ライブラリPyPdfを使う。それをwxPythonでラップした。

  • 必要環境
  • 使い方
    • ソースPdfMerger.pyをダブルクリックするだけで起動する(図1)
    • 結合したい複数のpdfファイルを一つずつ選択する(図2)
    • 選択が終わったら、出力ファイル名を指定する(図3)
    • ボタンを押してそれらをマージする(図3)


図1:起動画面

図2:結合したいpdfファイルの選択(いくつ選んでも良い)

図3:一つのpdfファイルとする

コードは以下の通り。

#!/bin/env python
# coding: utf-8
# PdfMerger.py                                  (2009/01/09 12:19:30)
#------------------------------------------------------------------------
import wx
import wx.grid
import os, sys
import time
from pyPdf import PdfFileWriter, PdfFileReader

wildcard1 = "pdf file (*.pdf)|*.pdf|" \
            "All files (*.*)|*.*"

class MainFrame(wx.Frame):       
    def __init__(self, id, title):
        width, height = 530,350
        wx.Frame.__init__(self, id, title=u"Merging Pdf Files",
                          size=wx.Size(width, height))
        Pan = wx.Panel(self, -1)

        self.StTxt1 = wx.StaticText(Pan, -1,
                                    u"(1)ファイルを順番に選択する")
        self.Table  = DataTable(Pan)
        self.Btn1   = wx.Button(Pan, -1, u"(1)ファイルの選択")        
        self.StTxt2 = wx.StaticText(Pan, -1,
                                    u"(2)選択したすべてのファイルを結合する")
        self.StTxt3 = wx.StaticText(Pan, -1, u"結合したあとのファイル名:")
        self.TxtCtl = wx.TextCtrl(Pan, -1, "Enter file name",
                                  size=(250,-1))        
        self.Btn2   = wx.Button(Pan, -1, u"(2)ファイルの結合")
        self.Btn1.Bind(wx.EVT_BUTTON, self.SelectFiles)
        self.Btn2.Bind(wx.EVT_BUTTON, self.DoMerge)

        vsizer0  = wx.BoxSizer(wx.VERTICAL)        
        vsizer11 = wx.BoxSizer(wx.VERTICAL)
        vsizer21 = wx.BoxSizer(wx.VERTICAL)        
        hsizer11 = wx.BoxSizer(wx.HORIZONTAL)        
        hsizer21 = wx.BoxSizer(wx.HORIZONTAL)

        hsizer11.Add(self.Table, 0, wx.ALIGN_LEFT|wx.ALL, 5)
        hsizer11.Add(self.Btn1,  0, wx.ALIGN_LEFT|wx.ALL, 5)
        vsizer11.Add(self.StTxt1,0, wx.ALIGN_LEFT|wx.ALL, 5)
        vsizer11.Add(hsizer11,0, wx.ALIGN_LEFT|wx.ALL, 5)
        
        hsizer21.Add(self.StTxt3,0, wx.ALIGN_LEFT|wx.ALL, 5)
        hsizer21.Add(self.TxtCtl,0, wx.ALIGN_LEFT|wx.ALL, 5)
        hsizer21.Add(self.Btn2,  0, wx.ALIGN_LEFT|wx.ALL, 5)
        vsizer21.Add(self.StTxt2,0, wx.ALIGN_LEFT|wx.ALL, 5)
        vsizer21.Add(hsizer21,   0, wx.ALIGN_LEFT|wx.ALL, 5)
        vsizer0.Add(vsizer11, 0, wx.ALIGN_LEFT|wx.ALL, 5)
        vsizer0.Add(vsizer21, 0, wx.ALIGN_LEFT|wx.ALL, 5)

        Pan.SetSizer(vsizer0)
        vsizer0.Fit(Pan)

    def SelectFiles(self, event):
        dlg = wx.FileDialog(
            self, message=u"pdfファイルをひとつ選んでください",
            defaultDir=os.getcwd(),
            defaultFile="",
            wildcard=wildcard1, style=wx.OPEN|wx.CHANGE_DIR)

        if dlg.ShowModal() == wx.ID_OK:
            self.Table.VNumber += 1
            title = dlg.GetFilename()
            input_temp = PdfFileReader(file(title, "rb"))
            pnumber = input_temp.getNumPages()
            self.Table.TitleList.append(title)
            self.Table.PageNumber.append(pnumber)
            self.Table.UpdateList(title, pnumber)
        dlg.Destroy()

    def DoMerge(self, event):
        outputfile = self.TxtCtl.GetValue()
        if outputfile[-3:] != 'pdf':
            outputfile += '.pdf'
        output = PdfFileWriter()
        for i in xrange(self.Table.VNumber):
            input = PdfFileReader(file(self.Table.TitleList[i], "rb"))
            pnum = input.getNumPages()
            for k in xrange(pnum):
                output.addPage(input.getPage(k))
                
        outputStream = file(outputfile, "wb")
        output.write(outputStream)
        outputStream.close()
        print "PdfMerger: merging is completed successfully\
 at %s." % time.ctime(time.time())
        
class DataTable(wx.grid.Grid):
    def __init__(self, parent):
        wx.grid.Grid.__init__(self, parent, -1)

        self.InitRow = 8
        self.CreateGrid(self.InitRow, 2)
        self.SetColLabelValue(0, u"ファイル名")
        self.SetColLabelValue(1, u"ページ数")
        self.SetColSize(0, 240)
        self.SetColSize(1, 60)

        self.VNumber = 0
        self.TitleList = []
        self.PageNumber = []

    def UpdateList(self, filen, pnumber):
        RowNum = self.VNumber
        if RowNum > self.InitRow:
            self.AppendRows(RowNum-self.InitRow)
            self.InitRow = RowNum
        self.SetCellValue(RowNum-1, 0, self.TitleList[RowNum-1])
        self.SetCellValue(RowNum-1, 1,
                          str(self.PageNumber[RowNum-1]))

class Application(wx.App):
    def OnInit(self):
        frame = MainFrame(None, -1)
        frame.Show(True)
        self.SetTopWindow(frame)
        return True

def main():
    app = Application(0)
    print u"info> このアプリケーションの起動時刻は %sです。" %\
            time.ctime(time.time())
    print u"info> 起動ディレクトリは %sです。" % os.getcwd()
    app.MainLoop()

if __name__ == '__main__':
    main()
#eof