2016年2月7日日曜日

XPSファイルをページ単位で分割

かなり久しぶりの投稿ですw

仕事でDocumentViewerにExcelの印刷プレビューを表示する必要ができて、どうしようかなぁと考えて見たんだけど、一旦XPSに出力してから読み込めばいいやって結論になっったんで、ちょこちょこっと作ってみました。

まずはエクセルをXPSに変換するところ
        private void ConvertExcelToXps(string excelFile, string xpsFile)
        {
            // COMオブジェクト宣言とEXCEL読み込み
            Excel.Application app = new Excel.Application();
            Excel.Workbooks books = app.Workbooks;
            Excel.Workbook book = books.Open(excelFile);
            // Excel → XPS 変換
            book.ExportAsFixedFormat(Excel.XlFixedFormatType.xlTypeXPS, xpsFile);
            // COM解放
            book.Close();
            Marshal.ReleaseComObject(book);
            book = null;
            books.Close();
            Marshal.ReleaseComObject(books);
            books = null;
            app.Quit();
            Marshal.ReleaseComObject(app);
            app = null;
        }
(どうでもいいけど、COM操作ってホントめんどくさい。。)

で、変換したXPSを読み込んでDocumentViewerに設定
            using (var doc = new XpsDocument(xpsFile, FileAccess.Read))
            {
                this.documentViewer.Document = doc.GetFixedDocumentSequence();
            }

完成!! 簡単、簡単♪♪

と思っていたら、

「ページ送りのボタンをつけてよ」
「はい? マウスホイールでスクロールできますよ」
「いや、前頁ボタンとか次頁ボタンでページを切り替えたいの」
「なんで?」
「だって、客がそういうから。。。」
「だから何で、客はそう言うの?」
「知らん。仕様なんだからやれよ」
「・・・・」

というわけで、DocumentViewerには1ページずつ表示することになりました。。。
でも、どうやって?

DocumentViewerにはそれっぽいプロパティはなさそうだし、どうしようかなと思っていたらさっきのヤツが

「1シートずつXPSにすればいいんじゃないの?」
「1シートが2ページ以上になることはないんですか?」
「・・・・あるね。」
「フッターにページ番号ついてませんでしたっけ?あれはどうするんですか?」
「・・・・ダメだね。」


結局、「Excel →(変換)→ XPS →(分割)→ ページ毎のXPS 」という流れでXPSファイルを作ることにしました。
が、これがわからなくて結構めんどくさかった。

最終的にはこんな感じで XPSをページ単位に分割できました。
        private int SeparateXps(string sourceXpsFile, string destDirectory)
        {
            int count = 0;
            // 分割後のファイルパスのフォーマット
            string fileFormat = destDirectory + Path.GetFileNameWithoutExtension(sourceXpsFile) + "{0}" + Path.GetExtension(sourceXpsFile);
            using (var source = new XpsDocument(sourceXpsFile, FileAccess.Read))
            {
                // 元のXPSファイルを読み込む
                var doc = source.GetFixedDocumentSequence();
                // ページ数を取得(戻り値用)
                count = doc.DocumentPaginator.PageCount;
                // 元のXPSファイルを1ページずつ処理
                for (int i = 0; i < count; i++)
                {
                    using (var destination = new XpsDocument(string.Format(fileFormat, i + 1), FileAccess.Write))
                    {
                        // 1ページずつに分割したXPSファイルを作成
                        var writer = XpsDocument.CreateXpsDocumentWriter(destination);
                        // 作成した1ページ分のXPSファイルに元のXPSファイルからVisualをコピー
                        writer.Write(doc.DocumentPaginator.GetPage(i).Visual);
                    }
                }
            }
            return count;
        }

作ったXPSを全部読み込んでList<FixedDocumentSequence>に保持。
前頁、次頁ボタンでDocumentViewerのDocumentを切り替えてやることで何とか行けそう。

でも、これだとページ数が多いとけっこう重くなりそうな気がする。

まぁ、いいや。
その時は、またその時考えようw

0 件のコメント:

コメントを投稿