アプリにOfficeドキュメントを同梱し、アプリ内からこれを開く方法と、Windows PCにOfficeがインストールされていない場合に、Office Onlineを使って対処する方法を解説する。
powered by Insider.NET
Windows Phoneには標準でOfficeが搭載されている。ならば、WordやExcelやPowerPointのファイル(以降、Office文書ファイル)をアプリに格納しておいて、アプリから開けないだろうか? 例えば、操作マニュアルをWordファイルで提供するといった用途が考えられる。そこで本稿では、ユニバーサルWindowsアプリに同梱したOffice文書ファイルをアプリから開く方法と、OfficeがインストールされていないWindows環境での対策を解説する。なお、本稿のサンプルは「Windows Store app samples:MetroTips #79」からダウンロードできる。
ユニバーサルプロジェクトを使ってユニバーサルWindowsアプリを開発するには、以下の開発環境が必要である。本稿では、無償のVisual Studio Express 2013 for Windowsを使っている。
*1 SLAT対応ハードウェアは、Windows Phone 8.1エミュレーターの実行に必要だ。ただし未対応でも、ソースコードのビルドと実機でのデバッグは可能だ。SLAT対応のチェック方法はMSDNブログの「Windows Phone SDK 8.0 ダウンロードポイント と Second Level Address Translation (SLAT) 対応PCかどうかを判定する方法」を参照。なお、SLAT対応ハードウェアであっても、VM上ではエミュレーターが動作しないことがあるのでご注意願いたい。
*2 事前には「Windows 8.1 Update 1」と呼ばれていたアップデート。スタート画面の右上に検索ボタンが(環境によっては電源ボタンも)表示されるようになるので、適用済みかどうかは簡単に見分けられる。ちなみに公式呼称は「the Windows RT 8.1, Windows 8.1, and Windows Server 2012 R2 update that is dated April, 2014」というようである。
*3 Windows Phone 8.1エミュレーターを使用しないのであれば、32bit版のWindows 8.1でよい。
*4 マイクロソフトのダウンロードページから誰でも入手できる。
*5 本稿に掲載したコードを試すだけなら、無償のExpressエディションで構わない。Visual Studio Express 2013 Update 2 for Windows(製品版)はマイクロソフトのページから無償で入手できる。Expressエディションはターゲットプラットフォームごとに製品が分かれていて紛らわしいが、Windowsストアアプリの開発には「for Windows」を使う(「for Windows Desktop」はデスクトップで動作するアプリ用)。
本稿では、紛らわしくない限り次の略称を用いる。
Visual Studio 2013 Update 2のRTMがリリースされたが、残念なことに本稿執筆時点ではVB用のユニバーサルプロジェクトのテンプレートがまだ含まれていない*6。そのため、本稿で紹介するコードはC#のユニバーサルプロジェクトだけとさせていただく。別途公開しているサンプルコードには、ユニバーサルプロジェクトに似せた形のVBのコードも含めてある*7。
*6 VB用のユニバーサルプロジェクトも近い将来に提供されるものと思われる。例えば、Windowsストアアプリ用のVBプロジェクトのCommonフォルダーに自動生成される「NavigationHelper.vb」ファイルには、Phoneの[戻る]ボタン(ハードウェアボタン)からの割り込みを処理するためのコードがUpdate 2ですでに追加されている。これはユニバーサルプロジェクトのために必要になるコードであり、ユニバーサルプロジェクトを提供する予定がないのなら不要なものだ。
*7 プロジェクト間のファイルリンクを使えば、VBでもユニバーサルプロジェクトに似たソリューション構成にできる。別途公開のサンプルコードでは、VBでもWindows用/Phone用/共通コードの3プロジェクトに分けてユニバーサルプロジェクトに似せて書いてみた。ただし、このような形にするにはかなりの手間が掛かった(説明するには本連載の1回分では足りないほどだ)。ユニバーサルプロジェクトテンプレートの形にこだわらず、素直に作った方がよさそうである。なお、ユニバーサルプロジェクトで作らなくてもユニバーサルWindowsアプリはリリースできるので、お間違えなきよう(「WinRT/Metro TIPS:ユニバーサルプロジェクトで開発するには?」参照)。
プロジェクト内に置いて、「コンテンツ」にすればよい。ユニバーサルプロジェクトの場合は、共有プロジェクトに置ける。
例として適当なPowerPointのファイルを作り、ファイル名を「sample.pptx」とする(ソリューションとは別のフォルダーに作成したとする)。VS 2013のソリューションエクスプローラーで、まず共有プロジェクトに適当なフォルダー(ここでは「Assets」とする)を作る。続いて、作成した「Assets」フォルダーを右クリックして[追加]−[既存の項目]を選び、「sample.pptx」ファイルを指定する。そうしたら、「sample.pptx」ファイルのプロパティで、[ビルド アクション]を「コンテンツ」にする(次の画像)。画像やフォントを同梱するのと同じである。
LaunchFileAsyncメソッド(Windows.System名前空間のLauncherクラス)を使えばよい。ただし、アプリに同梱したファイルは他のアプリ(ここではPowerPoint)からアクセスできないので、一時フォルダーにコピーしてから開く(デバッグ実行時はインストール場所が違うのでアクセス可能だ。気を付けよう)。
まず、アプリに同梱したファイルを一時フォルダーにコピーするコードは次のようになる。
// アプリに同梱するOfficeファイル
const string SampleFolder = "Assets";
const string SampleFileName = "sample.pptx";
// アプリに同梱したOfficeファイルを一時フォルダーにコピーして、それを返す
private static async System.Threading.Tasks.Task<Windows.Storage.StorageFile>
GetOfficeFileAsync()
{
var tempFolder = Windows.Storage.ApplicationData.Current.TemporaryFolder;
var tempFile = (await tempFolder.TryGetItemAsync(SampleFileName))
as Windows.Storage.StorageFile;
// すでにコピー済みなら、それを返す
if (tempFile != null)
return tempFile;
// 一時フォルダーにコピーしてそのファイルを返す
var installedFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
var sampleFolder = await installedFolder.GetFolderAsync(SampleFolder);
var srcFile = await sampleFolder.GetFileAsync(SampleFileName);
return await srcFile.CopyAsync(
tempFolder, SampleFileName,
Windows.Storage.NameCollisionOption.ReplaceExisting
);
}
ただし、PhoneのAPIにはTryGetItemAsyncメソッド(Windows.Storage名前空間のStorageFolderクラス)が存在しないので、新しくStorageFolderExtensionsクラスを作って、そこに拡張メソッドとして実装する(次のコード)。
#if WINDOWS_PHONE_APP
public static class StorageFolderExtensions
{
public static async System.Threading.Tasks.Task<Windows.Storage.IStorageItem>
TryGetItemAsync(this Windows.Storage.StorageFolder folder, string name)
{
var files = await folder.GetItemsAsync().AsTask().ConfigureAwait(false);
return files.FirstOrDefault(p => p.Name == name);
// FirstOrDefaultメソッドの使用には、ファイル冒頭に「using System.Linq;」が必要
}
}
#endif
先のGetOfficeFileAsyncメソッドで得られたファイルを開くコードは次のようだ。
public static async System.Threading.Tasks.Task OpenOfficeDocumentAsync()
{
var officeFile = await GetOfficeFileAsync();
var opt = new Windows.System.LauncherOptions();
await Windows.System.Launcher.LaunchFileAsync(officeFile, opt);
}
あとは画面にボタンを配置し、そのClickイベントで上述のOpenOfficeDocumentAsyncメソッドを呼び出せば、アプリに同梱したOffice文書ファイルが表示される(次の画像)。OpenOfficeDocumentAsyncメソッドは非同期メソッドなので、ボタンのClickイベントハンドラーにasyncキーワードの追加を忘れずに(次のコード)。
private async void Button_Click(object sender, RoutedEventArgs e)
{
await AttachedOfficeFiles.OpenOfficeDocumentAsync();
}
上記のコードは、Office(あるいは、Office文書ファイルを表示するアプリ)がインストールされていないWindowsではうまくいかない(PhoneにはOfficeが標準なので心配はない)。その対策として、同じOffice文書ファイルをOneDriveに置いておき、Office Onlineで開くようにするとよい。
まず、前述の「sample.pptx」ファイルをOneDriveの公開可能なフォルダーにコピーし、[表示のみ可能]にしておく(次の画像)。
続いて、Internet ExplorerでOneDriveに置いた「sample.pptx」ファイルをクリックする(上の画像の画面でクリックする)。すると「PowerPoint Online」に切り替わって、PowerPointのファイルが表示されるので、そのURLをコピーしてどこかにメモしておく(次の画像)。
さて、OfficeがインストールされていないWindowsでは、上記のPowerPoint OnlineのURLを開いてやればよい。そのために利用できるのが、LauncherOptionsオブジェクトのFallbackUriプロパティだ。ファイルの関連付けでは開けなかったとき、FallbackUriプロパティに指定したWebページを自動的に開いてくれるのだ。
前述のOpenOfficeDocumentAsyncメソッドを、次のコードのように変更する。
// OneDriveにアップロードしたOfficeファイルのURL
const string SampleUrl
= "https://onedrive.live.com/view.aspx?cid=1F……省略…31&app=PowerPoint";
public static async System.Threading.Tasks.Task OpenOfficeDocumentAsync()
{
var officeFile = await GetOfficeFileAsync();
var opt = new Windows.System.LauncherOptions();
#if WINDOWS_APP
// 表示できるアプリがインストールされていないときの代替Uri
opt.FallbackUri = new Uri(SampleUrl);
#endif
await Windows.System.Launcher.LaunchFileAsync(officeFile, opt);
}
これで実行してみると、PowerPointがインストールされていないWindowsでは、次の画像のようにPowerPoint Onlineで表示される。なお、厳密にテストするにはPowerPointをアンインストールすべきであろうが、「sample.pptx」ファイル(および、コード内の定数)の拡張子を関連付けのないもの(例えば「.notpptx」など)に変更してしまえば動作を確認できる。
PhoneにはOffice ハブが標準だ。これを利用しない手はないだろう。また、OfficeがインストールされていないWindowsでも、OneDriveとPowerPoint Onlineを利用すればOffice文書を表示できる。
ユニバーサルプロジェクトでは、それらのコードを共有プロジェクトに置ける。
なお、本稿では筆者のOneDriveを使ったが、多数のアクセスが見込まれるアプリでは、ユーザーの許可を得た上でユーザーのOneDriveにアップロードした方がよいだろう。
Copyright© Digital Advantage Corp. All Rights Reserved.