概要
大量のシートから成るExcelファイルを一気にPDF化出来るツールを作りたいと思い、調べてみたら良さそうな記事をネットで見つけました。そのままでも十分使える機能を備えていますが、エラーハンドリングや保存ディレクトリの作成機能など、幾つか改良点を見出したので、自分なりに改良を加えたツールを完成させました。
事の起こり
筆者の父親から大量のシートから成るExcelファイルをPDF化する方法について相談を受けました。筆者自身の環境であれば、Pythonなどのプログラミング言語の開発環境を駆使してツールを作るところですが、父親のPCに開発環境を入れる訳にもいきません。。。よって、インストール作業などが不要で、なおかつ簡単に使えるツールを作ることにしました。調べてみたところ、WindowsにはJScriptというMicrosoftが開発したJavaScriptライクな言語がデフォルトでインストールされているため、これを活用すれば出来そうです。
PowerShellでも同様のことが出来ると思われますが、筆者は宗教上の理由でPowerShellは使わないため、JScriptで実装しました。
本来はモジュール毎にソースファイルを分けるべきかもしれませんが、利用される環境の事情を考慮して1つのソースファイルにまとめて実装することにしました。
Excel to PDFツール
以下のWebページでExcelファイルをPDF化するツールの作り方が掲載されています。
JScriptでツールを作る時は、文字コードをShift-JIS(ANSI)に設定する必要が有ります。
改良案
- 自動的にファイル名からディレクトリを作成し、その中にPDFファイルを格納する
- エラーハンドリング
- リファクタリング
改良版ソース
上記改良案を反映したソースが以下です。
// ExcelファイルをPDFに変換する
function ExportPDF(fname) {
var fs = new ActiveXObject("Scripting.FileSystemObject");
// フォルダパスを取得
var parentPath = fs.GetFile(WScript.ScriptFullName).ParentFolder
// ファイル名を取得
var fileName = fs.GetBaseName(fname);
var folderName = fileName;
// 出力フォルダ名を設定
var outputPath = parentPath + "/" + folderName;
if(fs.FolderExists(outputPath)) {
WScript.Echo(folderName + "は既に存在します");
WScript.Quit();
} else {
fs.CreateFolder(outputPath);
}
// 出力先、ファイル名を設定
var output = outputPath + "/" + fileName;
// Excelを開き、PDFに変換する
var book = excel.Workbooks.Open(fname);
var sheets = book.worksheets;
for (var i = 1; i <= sheets.Count; i++) {
// シート名を取得
var sheetName = sheets(i).name;
// PDFファイル名を設定
var pdfFileName = output + "_" + sheetName;
try {
sheets(i).ExportAsFixedFormat(0, pdfFileName, 0, true, false);
} catch(e) {
WScript.Echo("ファイルが壊れているか、変換対象が存在しません");
book.Close();
excel.Quit();
fs.DeleteFolder(outputPath, true);
WScript.Quit();
}
}
book.Close();
}
// ドラッグ&ドロップされたファイルを確認する
if (WScript.Arguments.Count() == 0) {
WScript.echo("ファイルがありません");
WScript.Quit();
}
// Excelを起動する
var excel = WScript.CreateObject("Excel.Application");
excel.Visible = true;
// 1ファイルずつPDFに変換する
for (var i = 0; i < WScript.Arguments.Count(); i++) {
ExportPDF(WScript.Arguments.Item(i));
}
excel.Quit();
WScript.echo("変換完了");
更に改良版
- Wordファイルにも対応(拡張子で判定)
function ExcelToPDF(fname, fs) {
// ファイル名を取得
var fileName = fs.GetBaseName(fname);
var folderName = fileName;
// フォルダパスを取得
var parentPath = fs.GetFile(WScript.ScriptFullName).ParentFolder
// 出力フォルダ名を設定
var outputFolder = parentPath + "/" + folderName;
if(fs.FolderExists(outputFolder)) {
WScript.Echo(folderName + "は既に存在します");
WScript.Quit();
} else {
fs.CreateFolder(outputFolder);
}
// 出力先、ファイル名を設定
var outputPath = outputFolder + "/" + fileName;
// Excelを起動する
var excel = WScript.CreateObject("Excel.Application");
excel.Visible = true;
// Excelを開き、PDFに変換する
var book = excel.Workbooks.Open(fname);
var sheets = book.worksheets;
for (var i = 1; i <= sheets.Count; i++) {
// シート名を取得
var sheetName = sheets(i).name;
// PDFファイル名を設定
var pdfFileName = outputPath + "_" + sheetName;
try {
sheets(i).ExportAsFixedFormat(0, pdfFileName, 0, true, false);
} catch(e) {
WScript.Echo("ファイルが壊れているか、変換対象が存在しません");
book.Close();
excel.Quit();
fs.DeleteFolder(outputFolder, true);
WScript.Quit();
}
}
book.Close();
excel.Quit();
}
function WordToPDF(fname, fs) {
// ファイル名を取得
var fileName = fs.GetBaseName(fname);
var folderName = fileName;
// フォルダパスを取得
var parentPath = fs.GetFile(WScript.ScriptFullName).ParentFolder
// 出力フォルダ名を設定
var outputFolder = parentPath + "/" + folderName;
if(fs.FolderExists(outputFolder)) {
WScript.Echo(folderName + "は既に存在します");
WScript.Quit();
} else {
fs.CreateFolder(outputFolder);
}
// 出力先、ファイル名を設定
var outputPath = outputFolder + "/" + fileName;
// Wordを起動する
var word = WScript.CreateObject("Word.Application");
word.Visible = true;
// Wordを開き、PDFに変換する
var doc = word.Documents.Open(fname);
try {
doc.SaveAs(outputPath ,17);
} catch(e) {
WScript.Echo("ファイルが壊れているか、変換対象が存在しません");
doc.Close();
word.Quit();
fs.DeleteFolder(outputFolder, true);
WScript.Quit();
}
doc.Close();
word.Quit();
}
// Excel, WordファイルをPDFに変換する
function ExportPDF(fname) {
var fs = new ActiveXObject("Scripting.FileSystemObject");
// 拡張子を取得
var exts = fs.GetExtensionName(fname);
if (exts === "xlsx") {
ExcelToPDF(fname, fs);
} else if (exts === "docx") {
WordToPDF(fname, fs);
} else {
WScript.Echo("ファイル形式が不正です");
WScript.Quit();
}
}
// ドラッグ&ドロップされたファイルを確認する
if (WScript.Arguments.Count() == 0) {
WScript.echo("ファイルがありません");
WScript.Quit();
}
// 1ファイルずつPDFに変換する
for (var i = 0; i < WScript.Arguments.Count(); i++) {
ExportPDF(WScript.Arguments.Item(i));
}
WScript.echo("変換完了");
まとめ
無事ツールが完成しました。これで複数のExcelファイル、WordファイルのPDF化を簡単かつ高速に手間無く実現出来ました。
Reference