ExCella Reports1.4のライブラリを使用し帳票・ExcelをLibreOffice3経由でPDFで出力します(成功しました)。
【準備】
1.「LibreOffice3.6.7のインストール方法」の手順で、LibreOffice3をインストールしておきます。
【手順1】
1.「C:\Program Files (x86)\LibreOffice 3」に移動。
2.「ure-link」を選択し、右クリックから「コピー」を選択。
1.「Ctrl+V」で貼り付け。
2.「続行」ボタンをクリック。
1.「ure-link - コピー」を選択し、右クリックから「名前の変更」を選択。
1.「続行」ボタンをクリック。
1.「basis-link」と入力。
1.「ノートパッドを管理者権限で起動する方法」の手順で、ノートパッドを管理者権限で起動。
2.メニューから「ファイル」⇒「開く」を選択。
1.「すべてのファイル」を選択。
1.「basis-link」を選択。
2.「開く」ボタンをクリック。
1.以下の内容を入力。
.
1.メニューから「ファイル」⇒「上書き保存」を選択。
1.「Javaプロジェクトの作成方法」の手順で、「ExCellaSample041-PdfLibreOffice3OK」といプロジェクトを作成。
2.「excella-reports-1.4.jarとそれに依存ライブラリを設定する方法」の手順で、プロジェクトにExCella Reports1.4とそれに依存するライブラリを追加。
3.「ExCella Reports1.4のJDOConverterのバージョンアップ方法」の手順で、JODConverterをバージョンアップ。
4.「PdfLibreOffice3OKTemplate.xls」という名前の、以下の様なテンプレートファイルを作成し、「ExCellaSample041-PdfLibreOffice3OK」直下に配置。
5.「Javaクラスファイルの作成方法」の手順で、「Main」というクラスを作成。
6.「Main.java」を以下の様に入力。
import org.bbreak.excella.reports.exporter.OoPdfExporter; import org.bbreak.excella.reports.model.ReportBook; import org.bbreak.excella.reports.model.ReportSheet; import org.bbreak.excella.reports.processor.ReportProcessor; import org.bbreak.excella.reports.tag.SingleParamParser; public class Main { public static void main(String[] args) throws Exception { String templateFilePath = "PdfLibreOffice3OKTemplate.xls"; String outputFileName = "PdfLibreOffice3OK"; String outputFileDir = ""; String outputFilePath = outputFileDir.concat(outputFileName); ReportBook outputBook = new ReportBook(templateFilePath, outputFilePath, OoPdfExporter.FORMAT_TYPE); ReportSheet outputSheet = new ReportSheet("請求書"); outputBook.addReportSheet(outputSheet); outputSheet.addParam(SingleParamParser.DEFAULT_TAG, "値1", "値1に入るHello, World"); outputSheet.addParam(SingleParamParser.DEFAULT_TAG, "値2", "値2に入るHello, World"); outputSheet.addParam(SingleParamParser.DEFAULT_TAG, "値3", "値3に入るHello, World"); ReportProcessor reportProcessor = new ReportProcessor(); reportProcessor.process(outputBook); } }7.「Ctrl+Shift+O」を押し、パッケージのインポート文を補完。
8.「Ctrl+Shift+F」を押し、ソースコードをフォーマッティング。
9.「Javaパッケージの作成方法」の手順で「org.artofsolving.jodconverter.office」というパッケージを作成。
10.「Javaクラスファイルの作成方法」の手順で「OfficeProcess」というクラスを作成。
11.「OfficeProcess.java」を以下の様に入力。
// // JODConverter - Java OpenDocument Converter // Copyright 2004-2011 Mirko Nasato and contributors // // JODConverter is free software: you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License // as published by the Free Software Foundation, either version 3 of // the License, or (at your option) any later version. // // JODConverter is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General // Public License along with JODConverter. If not, see // <http://www.gnu.org/licenses/>. // package org.artofsolving.jodconverter.office; import static org.artofsolving.jodconverter.process.ProcessManager.PID_UNKNOWN; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.logging.Logger; import org.apache.commons.io.FileUtils; import org.artofsolving.jodconverter.process.ProcessManager; import org.artofsolving.jodconverter.process.ProcessQuery; import org.artofsolving.jodconverter.util.PlatformUtils; class OfficeProcess { private final File officeHome; private final UnoUrl unoUrl; private final String[] runAsArgs; private final File templateProfileDir; private final File instanceProfileDir; private final ProcessManager processManager; private Process process; private long pid = PID_UNKNOWN; private final Logger logger = Logger.getLogger(getClass().getName()); public OfficeProcess(File officeHome, UnoUrl unoUrl, String[] runAsArgs, File templateProfileDir, File workDir, ProcessManager processManager) { this.officeHome = officeHome; this.unoUrl = unoUrl; this.runAsArgs = runAsArgs; this.templateProfileDir = templateProfileDir; this.instanceProfileDir = getInstanceProfileDir(workDir, unoUrl); this.processManager = processManager; } public void start() throws IOException { start(false); } public void start(boolean restart) throws IOException { ProcessQuery processQuery = new ProcessQuery("soffice.bin", unoUrl.getAcceptString()); long existingPid = processManager.findPid(processQuery); if (existingPid != PID_UNKNOWN) { throw new IllegalStateException(String.format("a process with acceptString '%s' is already running; pid %d", unoUrl.getAcceptString(), existingPid)); } if (!restart) { prepareInstanceProfileDir(); } List<String> command = new ArrayList<String>(); File executable = OfficeUtils.getOfficeExecutable(officeHome); if (runAsArgs != null) { command.addAll(Arrays.asList(runAsArgs)); } command.add(executable.getAbsolutePath()); command.add("--accept=" + unoUrl.getAcceptString() + ";urp;"); // command.add("--env:UserInstallation=" + OfficeUtils.toUrl(instanceProfileDir)); command.add("--headless"); command.add("--nocrashreport"); command.add("--nodefault"); command.add("--nofirststartwizard"); command.add("--nolockcheck"); command.add("--nologo"); command.add("--norestore"); ProcessBuilder processBuilder = new ProcessBuilder(command); if (PlatformUtils.isWindows()) { addBasisAndUrePaths(processBuilder); } logger.info(String.format("starting process with acceptString '%s' and profileDir '%s'", unoUrl, instanceProfileDir)); process = processBuilder.start(); pid = processManager.findPid(processQuery); logger.info("started process" + (pid != PID_UNKNOWN ? "; pid = " + pid : "")); } private File getInstanceProfileDir(File workDir, UnoUrl unoUrl) { String dirName = ".jodconverter_" + unoUrl.getAcceptString().replace(',', '_').replace('=', '-'); return new File(workDir, dirName); } private void prepareInstanceProfileDir() throws OfficeException { if (instanceProfileDir.exists()) { logger.warning(String.format("profile dir '%s' already exists; deleting", instanceProfileDir)); deleteProfileDir(); } if (templateProfileDir != null) { try { FileUtils.copyDirectory(templateProfileDir, instanceProfileDir); } catch (IOException ioException) { throw new OfficeException("failed to create profileDir", ioException); } } } public void deleteProfileDir() { if (instanceProfileDir != null) { try { FileUtils.deleteDirectory(instanceProfileDir); } catch (IOException ioException) { File oldProfileDir = new File(instanceProfileDir.getParentFile(), instanceProfileDir.getName() + ".old." + System.currentTimeMillis()); if (instanceProfileDir.renameTo(oldProfileDir)) { logger.warning("could not delete profileDir: " + ioException.getMessage() + "; renamed it to " + oldProfileDir); } else { logger.severe("could not delete profileDir: " + ioException.getMessage()); } } } } private void addBasisAndUrePaths(ProcessBuilder processBuilder) throws IOException { // see // http://wiki.services.openoffice.org/wiki/ODF_Toolkit/Efforts/Three-Layer_OOo File basisLink = new File(officeHome, "basis-link"); if (!basisLink.isFile()) { logger.fine("no %OFFICE_HOME%/basis-link found; assuming it's OOo 2.x and we don't need to append URE and Basic paths"); return; } String basisLinkText = FileUtils.readFileToString(basisLink).trim(); File basisHome = new File(officeHome, basisLinkText); File basisProgram = new File(basisHome, "program"); File ureLink = new File(basisHome, "ure-link"); String ureLinkText = FileUtils.readFileToString(ureLink).trim(); File ureHome = new File(basisHome, ureLinkText); File ureBin = new File(ureHome, "bin"); Map<String, String> environment = processBuilder.environment(); // Windows environment variables are case insensitive but Java maps are // not :-/ // so let's make sure we modify the existing key String pathKey = "PATH"; for (String key : environment.keySet()) { if ("PATH".equalsIgnoreCase(key)) { pathKey = key; } } String path = environment.get(pathKey) + ";" + ureBin.getAbsolutePath() + ";" + basisProgram.getAbsolutePath(); logger.fine(String.format("setting %s to \"%s\"", pathKey, path)); environment.put(pathKey, path); } public boolean isRunning() { if (process == null) { return false; } return getExitCode() == null; } private class ExitCodeRetryable extends Retryable { private int exitCode; protected void attempt() throws TemporaryException, Exception { try { exitCode = process.exitValue(); } catch (IllegalThreadStateException illegalThreadStateException) { throw new TemporaryException(illegalThreadStateException); } } public int getExitCode() { return exitCode; } } public Integer getExitCode() { try { return process.exitValue(); } catch (IllegalThreadStateException exception) { return null; } } public int getExitCode(long retryInterval, long retryTimeout) throws RetryTimeoutException { try { ExitCodeRetryable retryable = new ExitCodeRetryable(); retryable.execute(retryInterval, retryTimeout); return retryable.getExitCode(); } catch (RetryTimeoutException retryTimeoutException) { throw retryTimeoutException; } catch (Exception exception) { throw new OfficeException("could not get process exit code", exception); } } public int forciblyTerminate(long retryInterval, long retryTimeout) throws IOException, RetryTimeoutException { logger.info(String.format("trying to forcibly terminate process: '" + unoUrl + "'" + (pid != PID_UNKNOWN ? " (pid " + pid + ")" : ""))); processManager.kill(process, pid); return getExitCode(retryInterval, retryTimeout); } }
12.「Ctrl+Shift+O」を押し、パッケージのインポート文を補完。
13.「Ctrl+Shift+F」を押し、ソースコードをフォーマッティング。
14.「Javaプロジェクトの実行方法」の手順で、「Main.java」を実行。
15.コンソールにエラーが出力されていないか確認。
(※コンソールが表示されていない場合は、「コンソール・ビューの表示方法」を確認)
16.「リフレッシュ(ローカルファイルとの同期)の方法」の手順で、プロジェクトをリフレッシュ。
17.「ExCellaSample041-PdfLibreOffice3OK/PdfLibreOffice3OK.pdf」が作成されています。
18.「ExCellaSample041-PdfLibreOffice3OK/PdfLibreOffice3OK.pdf」をダブルクリック。
19.「PdfLibreOffice3OK.pdf」が以下の様に開けば成功です。
【結論】
ExCellaからLibreOffice3経由でPDFを出力するには少々手を入れないと動きませんでした。
まずはライブラリの位置を指定する「ure-link」の配置が必要でした。
また、JODConveterでLibreOfficeを起動するオプションが「-」ではなく「--」である必用があるので「OfficeProcess.java」を修正する必要がありました。
PDFはLibreOffice3経由で作成した方が、OpenOffice3経由よりも線が細く、綺麗に変換されていると思います。
以上です。
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。