以前、FuelPHPでphpwordを使ってワードファイル(docx)を出力できるようにした時のメモ | Lunarian's Blogというエントリーをあげたのですが、その後、私が利用したphpwordをforkして進化したと思われるphpoffice/phpwordを発見しました(Github: PHPOffice/PHPWord · GitHub)。日本語に対応し、Pakagistにも登録(該当ページ:phpoffice/phpword – Packagist)があり、使い方は同じっぽいのでこちらを利用する方法に変更します。以下、使い方を簡単にメモ。

fuelPHPへの導入方法− composerをつかう

fuelPHPは、バージョン1.6からパッケージ管理にcomposerが利用されています。(composer公式サイト:Composer
phpoffice/phpword – Packagistがありますので、composerで導入することができます。

composer.json(composer.pharと同一フォルダにある)のrequire部分に、下記記載を追記。

あとは、ターミナル(黒い画面)で

で導入されます。phpwordは、ルートのvendorファイル下に配置され、class PHPWordにパスが通ります(という言い方が正しいかよくわからないけど、オートロードされるということ)。従って、普通に「new $phpword = new \PhpOffice\PhpWord\PhpWord();」でインスタンス生成で、利用できます。

使い方

↓こんな感じになります。
生成したワードファイル

参考リンク

FuelPHPとPHPWordのイメージ
【追記:2014/4/21】
以下で利用しているphpwordよりも新しいphpwordパッケージが見つかりました。そちらの方を利用する方が幸せになれると思いますので、コチラのエントリ:FuelPHPでphpoffice/phpwordを利用するメモ | Lunarian's Blogをご参照下さい。

職場で、簡単な業務用のアプリをFuelPHPで作っています。業務用アプリということで、文章を出力する機能が必要となり、PDF出力を利用していました。これについては、FuelPHP用にfuelpdfというパッケージ(fuel-packages/fuel-pdf · GitHub)があり、実装は簡単です。PDF出力ライブラリとしてTCPDFが利用されており、以前利用していたので簡単に実装できました。

ただ、どうしても取引先がMicrosoft Wordのファイルが良いという要望があり、こっちもそのためにWordを起動して手動でドキュメントを作る手間が馬鹿に出来なかったので、phpwordというPHPでMicrosoft Wordファイルを出力するPHPのライブラリをfuelPHPで利用できるようにしたまで奮闘した成果メモを記しておきます。

FuelPHPのパッケージへの理解、autoloadへの理解、フォルダ構成への理解などが不十分で結構とまどいましたが、とても簡単にできました。

phpwordの概要

生成できるのはWord2007形式

phpwordは、オープンソースのライブラリで、PHPでMicrosoft wordのファイルを出力するためのものです。
wordのファイルは、2003までの形式(*.doc)と2007移行の形式(*.docx)で中身が異なり、phpwordで出力できるのは、2007移行の形式(*.docx)になります。
なぜか2007移行の形式(*.docx)を毛嫌いしている人がたまに見受けられるのですが、Microsoft Office 2003は、XPのサポート終了と同時にサポートを終了してたりしますし、phpから2003までのword形式(バイナリファイル)を出力するのはかなり大変なので、そこはあきらめてほしいです。

生成方法は2通り

phpwordは、2つの方法でwordファイルを出力できます。
1つ目は、ワードファイルをテンプレートとして別途用意し、それを読み込んで編集(値を入れ替える)形で出力する方法。
2つ目は、一からワードファイルを生成する方法です。専用のオブジェクトを生成し、そのオブジェクトに一つ一つパーツを入れていき、最後に一つのワードファイルに生成します。

両方法のメリット・デメリット

1つ目は、ワードファイルをワードで編集して作っておくことが出来るなどのメリットがありますが、値を入れ替えるための変数の入力時などに若干面倒があります。また、プログラムの変更時にPHPとワードファイルと2つのソースを編集する必要があります。

2つ目の方法は、TCPDFなどでのやり方と同じなので慣れている人には楽です。またPHPで柔軟にドキュメント内容を変更できます。

私は2つ目の方法で主に利用するのですが、パスワード付きのドキュメントを取引先に指定されているので、その場合には、パスワードが付いたワードファイルのテンプレートを読み込むという形で1つめの方法で生成しています。(パスワードは固定なのでこの点ではそんなに手間はありません。セキュリティをそこまで厳密にする必要が無くて助かりました。phpwordには一からパスワード付きのファイルを生成する機能は無いようなので。)

phpwordの問題点:日本語への対応

問題として日本語への対応がされていないことが上げられます。
与えられた値に対して、PHP関数の「utf8_encode()」を適用してしまい、似非utf8でエンコードされてしまい文字化けする問題があります。これを手動で外す必要があります。
utf8_encode()という関数の名称から問題なさそうに思えるのですが、どうもちゃんとしたutf8にエンコードしてくれるわけではないとのことです。

fuelPHPへの導入方法その1− composerをつかう

(こちらの方法は、日本語対応で問題があるため、私は使っていません。)

fuelPHPは、バージョン1.6からパッケージ管理にcomposerが利用されています。(composer公式サイト:Composer
Packagistに、phpwordがありますので、composerで導入することができます。

composer.json(composer.pharと同一フォルダにある)のrequire部分に、下記記載を追記。

イメージ:
composer.jsonに追記する

あとは、ターミナル(黒い画面)で

ターミナル上でcomposer.phar updateする

で導入されます。phpwordは、ルートのvendorファイル下に配置され、class PHPWordにパスが通ります(という言い方が正しいかよくわからないけど、オートロードされるということ)。従って、普通に「new ¥PHPWord」でインスタンス生成で、利用できます。

この方法がオフィシャルな感じで一番正しい導入方法と思いますが、上述の日本語対応の問題を手動で修正しても「composer.phar update」時に新バージョンで上書きされてしまい、そのたびに修正しなければいけないのでは無いかと思います。(masterブランチしかないので)

そこで以下の方法でパッケージ化(というほどでもないけど)しました。

ちなみに、phpwordをforkしてutf8_encode()部分を消して、packagistに登録して、それでcomposerで導入という方法もありますが、めんどいのと、いろいろとアレなので私はやりません。

FuelPHPへの導入方法その2− packageにしてみる

fuelwordというそれっぽい名前でパッケージ化してみました。
なお、導入方法1と両方やった場合でどういつ名称だとcomposer導入の方が優先されるかと思います。

パッケージの構成と位置

fuel
├app
├core
├vendor
└packages
  └fuelword
    ├classes
     └fuelword.php
    ├config
    ├bootstrap.php
    └vendor
      └phpword(ダウンロードしてここに入れる)
        ├Examples
        ├PHPWord
        ├template
        └PHPWord.php

このような感じになります。fuelフォルダ下のpackagesフォルダ下に「fuelword」というフォルダを作成し、その下にclassesフォルダ、configフォルダ、vendorフォルダを作成。vendorフォルダ下に、PHPWordのページの「download」からphpword本体をダウンロード・解凍し、配置。

fuelwordフォルダの直下の「bootstrap.php」と、fuelword/classesフォルダの下に「fuelword.php」を自作します。私は以下の内容で自作しました。(下記は、フォルダ名、ファイル名が上記の通りであることを前提の内容)

ライセンスがどうなってるのかなど確認してないので問題があったら消します。

内容としては、たいしたことはしてません。他にスマートな方法がある気がしますが、時間が無いのでこれで済ませました。

実際に使ってみる

テンプレートから作成パターン

※テンプレートファイル(*.docx)は自分で用意

下記の参考リンクにも役立つ情報有りなので見てね。

1から作成パターン

↓こんな感じになります。
生成したワードファイル

参考リンク

ペリカン スーベレーン M400とロディアNo.16

私生活で色々あって人生の機微を味あわされています。金銭的には多少余裕があるのと買い物でストレス解消している面もあって、久々に万年筆が、それもペリカンのスーベレーンが欲しくなってしまいました。

先々週くらいから欲しいな〜と思い始めていて、先週もどんどんと物欲が増していき、昨日とうとう購入してしまいました。

ペリカンのスーベレーンシリーズは、長い歴史を持つ万年筆シリーズで、ドイツ語で「優れもの」を意味する「souveran」(スーベレーン)の名が冠されています。

現在では、M300からM1000まで、その軸の太さと長さによりタイプが分かれており、M300は小型で柔らかいペン先(ニブ)が採用されており、M400はやや小型で、汎用的なものであり、M800は大型スタンダードで独特の重量バランスがあり、M600はその中間に位置づけています。M1000は最大のもので柔らかいペン先が採用されており、極上の書き味とのことです。

ペリカン スーベレーン M400と他の万年筆の比較私は手が小さい方なので、M400くらいがちょうどいいなと思いつつ、M800は現在使用しているセーラー万年筆のプロフィット21・長刀研ぎとそんなに大きさが変わらないので、良いモノが欲しいと思う傾向の私としては、M800に惹かれていたのですが、普段良く使うキャップレス・デシモと比較してもそんなに変わらないM400のサイズ感がやはりぴったりなのかなとも思い、また速記に向き筆記試験向きでもあるということなので、M400にしました。

ペリカン スーベレーン M400の新デザインによりキャップトップが金メタルに最近ちょっとしたデザインリニューアルがあり、キャップ先がメタルの素材感になりました。黒地に金のペリカンマークの旧モデルも好きでしたが、実物を見てみるとこっちも高級感があり満足しています。

スーベレーンといえば、やはり緑縞かなという思いもあり、緑縞を購入しました。青縞もボルドー縞も茶縞も惹かれましたが、やはり緑縞かなと。M800はブラックと緑縞しか無いのでM800を購入予定の方で色をダブらせたく無い方は要注意ですが。

ペリカン スーベレーン M400の外観。透けてて軽い。実物を手にしてみるとインクが入っていない状態はとても軽くてびっくりしました。インクを入れて見るとほどよい重量感で、EF(極細)とはいえインクフローは滑らか。国産万年筆のF(細字)くらいの太さで、個人的にはもっと細い方が好みなのですが、滑らかさを捨てるよりは良いかなと思います。

ペリカン スーベレーン M400のペン先ペン先のデザインと緑縞、黒の光沢とメタルの質感からくるその佇まいは、高級感があり所有欲をこれでもかと満たしてくれます。

キャップレスデシモはペン先が柔らかくしなるような感触なのですが、M400はやや固く、それでも滑らかでしっかりとした筆記感があります。

書くという行為は、ずっとITだった自分だったからこそ、その良さが分かる気がします。毎日帰宅後、就寝前にでも何とはなしに思いやアイデアを書き記していきたいなぁと思っています。その良き友になってくれそうです。

写真ギャラリー

th_IMGP0826th_IMGP0830th_IMGP0832th_IMGP0834th_IMGP0837th_IMGP0841th_IMGP0842th_IMGP0843th_IMGP0844th_IMGP0846th_IMGP0847

もともと読書は好きだが、小説はほとんど読んだことが無かった。小説というものが、最も古く最も親しまれたエンターテイメントであることは認識しつつも、そこに嵌まることは無かった。あの文庫本の真っ白とは言いがたい黄色がかった紙を見ると、何か古くさいものを感じていた。それよりは、PCの画面を通してみる自分にはその裏の構造(HTML/CSS)まで透けて見える世界が好きだった。

数年ぶりに自分だけの自由な時間が出来て、それでも試験勉強なるめんどくさい大嫌いなものに向かわなければいけないときに、不意に活字を読みたい衝動に駆られた。同僚のかわいい子が小説が好きな子だったので、おすすめを借りたら、モノの見事に時間を切り取られるほど熱中した。その子はセンスが鋭く、また頭も良い子で、抜群に選択のセンスがあると感じていた。というか可愛い子だからそう思いたい。

そんな時に人生で初めて金銭的に余裕がある数ヶ月があり、そこで、前々から気になっていた電子書籍に手を出してみたくなった。自分としては、Androidタブレットは持っているし、電子ペーパー技術に興味があったし、充電の手間は嫌だったし、楽天が商売上手とは思っていないので、自然とAmazon Kindle PaperWhiteを選択した。安い方のWi−Fiのみモデルでも良かったが、そのとき金があったのと、やはりいつでもどこでも本が買えるという欲求を満たしてくれるのが、電子書籍の最大の利点だとも思っていたから、3G付きモデルを購入した。

安くて早くて旨い

Amazon Kindle PaperWhiteは、良く出来た端末で基本的に不満がないほど良く出来ている。それでいてAmazonが展開するKindleストアは、私のような小説を全然読まなかった男にしてみれば、安く大量に良い小説が読める最良のストアだ。とはいえ、実際の中古本よりも安くは無く、それでいて売ったりも出来ないのを価値に感じない人もいると思う。私はそうではなく、むしろ部屋に本がこれ以上増えないことを歓迎したい気持ちが勝る。本好きな人は紙じゃ無いと嫌だというし、本棚に並んだ本を見ているだけで満足できる人もいるだろう。実は私もその口で本棚に大量の本が並んでいる。しかし、それらは小説では無くほとんどが実用書か学術書だ。それらは実際の必要に駆られて並んでおり、すでにスペースを本棚2個分くらいオーバーしてオーバーした本は職場にあるか押し入れにあるかのどちらかになっている。私の場合、小説は一度読んだらまた再度読み直すことはほとんど無いだろうから、場所をとらずに、アカウント情報に紐付けられていつでも読みたいと思ったときに読める方が嬉しいのだ。

バックライト付き電子ペーパーは、夜のバルコニーでたばこを吸いながらでも読めるし、寝る前にも読める。また本体も軽く、電車で片手がつり革、片手がKindleで読み進めることも出来る。紙の本だとしおりが面倒だし、ドッグイヤーは好きじゃないし、ページをめくるのが片手だとうまくいかない。私は手が小さいし、そんなに器用でも無い。

それにくわえて、早川書房などが一斉にセールを行って、購入意欲をかぎ立ててくれて、あとは芋づる式に本をぽんぽん購入してしまっている。300円とか500円とかでAndroidのゲームアプリを買うこともあるけれど、それよりも財布のひもが緩んでいる。お得感があるし、自分が小説というものに嵌まってきていて、アプリよりも価値を見いだしているからだろう。

良さに気付くのはシリーズものに嵌まって止まらなくなったとき

「探偵はBARにいる」という映画が大泉洋主演でやっていたのを記憶していたが、その原作のススキノ探偵シリーズがセールになっていたので、第一作を読んでみたところ、大嵌まりしてしまった。もともと推理ものは好きだし、探偵モノも好きなので、当然なのかもしれないが、おもしろくて仕方が無い。

1冊読んで、また次のやつ、それも読み終わって、あぁ止まらない、次もだ!…と行くとき、次の日の朝の本屋が空く時間を待たなくて良く、またそのシリーズの次の買いたいヤツだけが本屋に在庫が無いという悔しい思いもしなくて良い。これがどれほど快適か、というのをこのKindleで思い知らされた。他方で、本を売る側からしても顧客の購買意欲が最大限高まったところを逃さなくて良いという利点があるのでは無いか。

小説というエンターテイメントは電子書籍でまた違う形を見せると思う

小説というエンターテイメントは、本屋や図書館、文芸雑誌や文学賞などで醸成されてきたと認識している。でも、このKindleは、それらをある種ケータイ小説に近いところに持って行くのだと思う。どこでもいつでも手軽に読めて、在庫に顧客が悩むことはなくなる。中間マージンが廃され、より多くの収益が数社の元締めと作家にもたらされるだろう。作家と読者がより強く繋がり、それらは多数の幸福と多数の不幸を招くだろう。小説はより身近で、より小粒な小説家がスマッシュヒットで食べていけるようになるかもしれない。それらは、小説の低廉化を招くが作家にはより多くの収益をもたらすとスマホアプリマーケットが一部証明している。
小説というエンターテイメントは、本屋や図書館、文芸雑誌や文学賞などで醸成されてきたと認識している。でも、このKindleは、それらをある種ケータイ小説に近いところに持って行くのだと思う。どこでもいつでも手軽に読めて、在庫に顧客が悩むことはなくなる。中間マージンが廃され、より多くの収益が数社の元締めと作家にもたらされるだろう。作家と読者がより強く繋がり、それらは多数の幸福と多数の不幸を招くだろう。小説はより身近で、より小粒な小説家がスマッシュヒットで食べていけるようになるかもしれない。それらは、小説の低廉化を招くが作家にはより多くの収益をもたらすとスマホアプリマーケットが一部証明している。

紙を愛する読者には受け入れられないかもしれないが、私のように小説の中の世界を愛する人間には幸せなことだと思う。より多くのより多様な作家が存在しうるエコシステムがすでに形成されつつあるのだ。
紙を愛する読者には受け入れられないかもしれないが、私のように小説の中の世界を愛する人間には幸せなことだと思う。

Sublime Text 2のイメージ

巷で話題の最高のテキストエディタ「Sublime Text 2」ですが、便利なのは多数のプラグインを簡単に追加出来ることかと思います。

その中で、HTML、CSS、JS、PHPなどのLint(文法チェック)をリアルタイム(保存時)に行ってくれるプラグインである「Sublime Linter」(GitHub)というプラグインがあります。

これを利用していて、どうもPHPだと動いてくれないという問題に遭遇しましたが、解決したのでその方法を以下に記します。

ちなみに、JavaScriptやCSSでは、nodejsの導入が必要です。そちらについては、詳しい他のサイトエントリを参照すれば簡単かと思います。(詳しい他のサイトエントリ:macのテキストエディタ Sublime Text2でJavaScriptのシンタックスエラーチェックをリアルタイムで行う方法 | clicktx::Tech::Memo

原因その1.PHP.exeの場所をちゃんと指定できてない。

この問題は、主にPHPにパスが通っていないWindowsで起きるようです。MacなんかはPHPにパスが通っている(ターミナルで「php -v」と打ってバージョンがちゃんと返ってくる)ので、設定は必要ないようです。

詳しくは、SublimeLinterのDefault設定ファイルに詳しく書いてあるのですが、必要なことは、SublimeLinterのUser設定ファイルに、php.exeへのパスを記入するということです。(もちろん環境変数をいじってパスを通すだけでもOKなようです)

  1. PHPのサイトから、Windows用のPHPバイナリを落とす
  2. 解凍して適当な位置に配置(仮にC:\php\とします。つまり、php.exeがあるのは、C:\php\php.exe)
  3. Sublime Text 2を起動して、上部メニューバーから「preferences」→「Package Settings」→「Sublime Linter」→「Settings – User」を開く
  4. 以下のように入力して保存する

原因その2.開いているPHPファイルのSyntaxがHTML5になっている

上記の原因その1については、デフォルトの設定ファイルを見れば分かるので特段躓かないかと思うのですが、次の問題はなかなか分からず四苦八苦したのですが、結構シンプルな問題でした。こちらのQ&Aサイト(Stack Overflow)を読んで解決しました。

どうやら、Sublime Text 2は、PHPファイルをHTML5のSyntaxで自動読み込みするらしく、それが原因ということのようです。ですので、コマンドメニュー(Ctrl+Shift+P)を開いて「syntax: php」と打って、syntaxをPHPに切り替えれば、ちゃんと動作します

なお、コンソール(Ctrl+@)にて、「sublime.active_window().active_view().settings().get(‘syntax’)」とコマンドを打つことで、現在開いているファイルをどのSyntaxで読み込んでいるかを確認できます。

たったこれだけですが、なんでこういう動作になってるかなぁ。。。という感じでした。