
DocRaptor: PDF 生成
この工程は、HTML から PDF ファイルを生成します。
Basic Configs
- 工程名
- メモ
Configs for this Auto Step
- conf_Auth
- C1: API キーをユーザ名に設定した BASIC 認証設定 *
- conf_SourceHtml
- C2: 変換元の HTML が保存されているデータ項目 *
- conf_Files
- C3: 生成された PDF ファイルを保存するデータ項目 *
- conf_DeleteOtherFiles
- C4: 保存時に他のファイルを削除する
- conf_FileName
- C5: 保存する際のファイル名 *#{EL}
Notes
- DocRaptor アカウントの API キーを、BASIC 認証のユーザ名として設定してください
- パスワードは空のままで問題ありません
- デバッグプロセスで生成された PDF ファイルには、DocRaptor のウォーターマークが付きます
- その代わり、DocRaptor アカウントのドキュメント生成回数を消費しません
- DocRaptor のウェブサイトにログインすると確認できるドキュメント生成ログは、「Questetra-m{アプリ ID}-p{プロセス ID}」の形式で作成されます
- 変換元の HTML をファイル型データ項目で指定する場合、
- 添付できるファイルは 1 つまでです
- ファイルサイズは最大 1MB (1,048,576 byte) までです
Capture

See Also
Script (click to open)
- 次のスクリプトが記述されている XML ファイルをダウンロードできます
- docraptor-pdf-generate.xml (C) Questetra, Inc. (MIT License)
- Professional のワークフロー基盤では、ファイル内容を改変しオリジナルのアドオン自動工程として活用できます
const MAX_SOURCE_FILE_SIZE = 1048576; // 1MB。標準アイテムではファイルの読み出しサイズに制限はないが、無制限もよくないので
function main(){
//// == 工程コンフィグ・ワークフローデータの参照 / Config & Data Retrieving ==
const auth = configs.get('conf_Auth');
const html = retrieveSourceHtml();
const filesDef = configs.getObject('conf_Files');
const deleteOtherFiles = configs.getObject('conf_DeleteOtherFiles');
const fileName = retrieveFileName();
//// == 演算 / Calculating ==
const statusId = generatePdf(auth, html);
// 処理状況を確認し、未完了なら proceed() に進む
if (checkStatusAndSaveFile(auth, statusId, filesDef, deleteOtherFiles, fileName) === false) {
engine.saveTemporaryData(statusId);
return false;
}
}
function proceed() {
//// == 工程コンフィグ・ワークフローデータの参照 / Config & Data Retrieving ==
const auth = configs.get('conf_Auth');
const filesDef = configs.getObject('conf_Files');
const deleteOtherFiles = configs.getObject('conf_DeleteOtherFiles');
const fileName = retrieveFileName();
//// == Restoring Temporary Data / 一時データの読み出し ==
const statusId = engine.restoreTemporaryData();
if (statusId === null) {
throw 'Temporary data has not been saved.';
}
//// == 演算 / Calculating ==
if (checkStatusAndSaveFile(auth, statusId, filesDef, deleteOtherFiles, fileName) === false) {
return false;
}
}
/**
* config に設定したファイル型/文字型データ項目から変換元 HTML を読み出す
* @return {String} html
*/
function retrieveSourceHtml() {
const sourceHtmlDef = configs.getObject('conf_SourceHtml');
if (sourceHtmlDef.matchDataType('FILE')) { // ファイル型データ項目の場合
return retrieveSourceHtmlFromFile(sourceHtmlDef);
}
// 文字型データ項目の場合
const html = engine.findData(sourceHtmlDef);
if (html === null) {
throw 'Source HTML is empty.';
}
return html;
}
/**
* ファイル型データ項目から変換元 HTML を読み出す
* @param {ProcessDataDefinitionView} sourceFilesDef
* @return {String} html
*/
function retrieveSourceHtmlFromFile(sourceFilesDef) {
const sourceFiles = engine.findData(sourceFilesDef);
if (sourceFiles === null) {
throw 'No source file attached.';
}
if (sourceFiles.size() > 1) {
throw 'More than one source files attached.';
}
const sourceFile = sourceFiles.get(0);
if (sourceFile.getLength() === 0) {
throw 'Source file is empty.';
}
if (sourceFile.getLength() > MAX_SOURCE_FILE_SIZE) {
throw 'Source file is too large.';
}
const contentType = sourceFile.getContentType();
if (!contentType.startsWith('text/html')) {
throw 'Content-Type of the source file is not text/html.';
}
return fileRepository.readFile(sourceFile, decideCharset(sourceFile));
}
/**
* config から保存する際のファイル名を読み出す
* 空の場合はエラー
* @return {String} fileName
*/
function retrieveFileName() {
const fileName = configs.get('conf_FileName');
if (fileName === '') {
throw 'File name is blank.';
}
return fileName;
}
/**
* ファイルの charset を読み出す
* charset が設定されていない場合は UTF-8 を返す
* @param {QfileView} sourceFile
* @return {String} charset
*/
function decideCharset(sourceFile) {
const charset = sourceFile.getCharset();
if (charset === null) {
return 'UTF-8';
}
return charset;
}
/**
* DocRaptor の PDF 生成 API に POST リクエストを送信し、ステータス ID を返す
* プロセスがデバッグ実行の場合、PDF 生成をテスト扱いにする
* @param {String} auth 認証設定名
* @param {String} html HTML ソース
* @return {String} statusId ステータス ID
*/
function generatePdf(auth, html) {
const requestBody = generateRequestBody(html);
const response = httpClient.begin()
.authSetting(auth)
.body(requestBody, 'application/json')
.post('https://api.docraptor.com/docs');
const status = response.getStatusCode();
const responseStr = response.getResponseAsString();
if (status !== 200) {
engine.log(responseStr);
throw `Failed to post PDF generation request. status: ${status}`;
}
return JSON.parse(responseStr).status_id;
}
/**
* PDF ファイル生成 API のリクエストボディを生成し、JSON 文字列で返す
* - 非同期生成をリクエスト
* - プロセスがデバッグ実行の場合、テストリクエスト扱いにする
* @param {String} html
* @return {String} requestBody
*/
function generateRequestBody(html) {
const requestBody = {
document_type: 'pdf',
document_content: html,
async: true,
name: `Questetra-m${processInstance.getProcessModelInfoId()}-p${processInstance.getProcessInstanceId()}`
};
// プロセスがデバッグ実行の場合、test パラメータに true を設定
if (processInstance.getProcessInstanceDebug()) {
requestBody.test = true;
}
return JSON.stringify(requestBody);
}
/**
* PDF ファイル生成の処理状態を確認し、完了していればファイルを保存する
* 未完了の場合は false を返す
* @param {String} auth 認証設定名
* @param {String} statusId ステータス ID
* @param {DataDefinitionView} filesDef ファイルを保存するデータ項目
* @param {boolean} deleteOtherFiles 添付されている他のファイルを削除するかどうか
* @param {String} fileName 保存ファイル名
* @return {boolean}
*/
function checkStatusAndSaveFile(auth, statusId, filesDef, deleteOtherFiles, fileName) {
const response = httpClient.begin()
.authSetting(auth)
.get(`https://docraptor.com/status/${statusId}`);
const status = response.getStatusCode();
const responseStr = response.getResponseAsString();
if (status !== 200) {
engine.log(responseStr);
throw `Failed to get PDF generation status. status: ${status}`;
}
const json = JSON.parse(responseStr);
switch (json.status) {
case 'failed':
engine.log(JSON.stringify(json));
throw 'Failed to generate PDF.';
case 'completed':
downloadAndSaveFile(auth, json.download_url, filesDef, deleteOtherFiles, fileName);
break;
default:
return false;
}
}
/**
* PDF ファイルをダウンロードし、を保存する
* @param {String} auth 認証設定名
* @param {String} downloadUrl ダウンロード先 URL
* @param {DataDefinitionView} filesDef ファイルを保存するデータ項目
* @param {boolean} deleteOtherFiles 添付されている他のファイルを削除するかどうか
* @param {String} fileName 保存ファイル名
* @return {boolean}
*/
function downloadAndSaveFile(auth, downloadUrl, filesDef, deleteOtherFiles, fileName) {
const response = httpClient.begin()
.authSetting(auth)
.get(downloadUrl);
const status = response.getStatusCode();
if (status !== 200) {
engine.log(response.getResponseAsString());
throw `Failed to download PDF file. status: ${status}`;
}
const qfile = new com.questetra.bpms.core.event.scripttask.NewQfile(
fileName, response.getContentType(), response.getResponse()
);
let files = engine.findData(filesDef);
if (files === null || deleteOtherFiles) {
files = new java.util.ArrayList();
}
files.add(qfile);
engine.setData(filesDef, files);
}