
Adobe: Generate PDF (HTML to PDF)
This item generates a PDF file from an HTML file, using Adobe PDF Services.
Basic Configs
- Step Name
- Note
Configs for this Auto Step
- conf_Auth
- C1: OAuth2 Setting *
- conf_HtmlDef
- C2: Data item that stores the source HTML file *
- conf_PageSize
- C3: PDF Page Size *
- conf_PdfDef
- C4: Data item to save the generated PDF file *
- conf_DeleteOtherFiles
- C5: Delete other files when saving
- conf_SaveAs
- C6: File name to save as *#{EL}
Notes
- See the Adobe PDF Services API Documentation to know how to get your Client ID and Client Secret for the authentication
Capture

See Also
Script (click to open)
- An XML file that contains the code below is available to download
- adobe-html-to-pdf.xml (C) Questetra, Inc. (MIT License)
- If you are using Professional, you can modify the contents of this file and use it as your own add-on auto step
/** PDF のレイアウト候補 (サイズはインチで指定) */
const LAYOUTS = {
'A4_P': {
pageWidth: 8.27,
pageHeight: 11.69
},
'A4_L': {
pageWidth: 11.69,
pageHeight: 8.27
}
};
/**
* tokenUrl: https://ims-na1.adobelogin.com/ims/token/v3
* scope: openid, AdobeID, DCAPI
* @returns {boolean}
*/
const main = () => {
const authSetting = configs.getObject('conf_Auth');
const htmlFile = retrieveHtmlFile();
const pageSize = configs.get('conf_PageSize');
validateFileName();
const {uploadUri, assetID} = createAsset(authSetting);
uploadHtml(uploadUri, htmlFile);
const statusUrl = htmlToPdf(authSetting, assetID, pageSize);
engine.saveTemporaryData(statusUrl);
return proceed();
};
const proceed = () => {
const authSetting = configs.getObject('conf_Auth');
const pdfDef = configs.getObject('conf_PdfDef');
const deleteOtherFiles = configs.getObject('conf_DeleteOtherFiles');
const fileName = configs.get('conf_SaveAs');
const statusUrl = engine.restoreTemporaryData();
return checkStatusAndSaveFile(authSetting, statusUrl, pdfDef, deleteOtherFiles, fileName);
};
/**
* config から変換元の HTML ファイルを読み出す
* @returns {QfileView}
*/
const retrieveHtmlFile = () => {
const htmlDef = configs.getObject('conf_HtmlDef');
const files = engine.findData(htmlDef);
if (files === null) {
throw 'No source file attached.'
}
if (files.size() > 1) {
throw 'More than one source files attached.';
}
const sourceFile = files.get(0);
if (sourceFile.getLength() === 0) {
throw 'Source file is empty.';
}
if (!sourceFile.getContentType().startsWith('text/html')) {
throw 'Content-Type of the source file is not text/html.';
}
return sourceFile;
};
/**
* config に設定された保存する際のファイル名をバリデーション
* 空の場合はエラー
*/
const validateFileName = () => {
const fileName = configs.get('conf_SaveAs');
if (fileName === '') {
throw 'File name to save as is blank.';
}
};
/**
* asset の作成
* @param authSetting
* @returns {any}
*/
const createAsset = (authSetting) => {
const body = JSON.stringify({
mediaType: 'text/html' // charset 付きでは指定できない
});
const response = httpClient.begin().authSetting(authSetting)
.header('x-api-key', authSetting.getClientId())
.body(body, 'application/json')
.post('https://pdf-services-ue1.adobe.io/assets');
const status = response.getStatusCode();
const respStr = response.getResponseAsString();
if (status !== 200) {
engine.log(respStr);
throw `Failed to create asset. status: ${status}`;
}
return JSON.parse(respStr);
};
/**
* HTML ファイルのアップロード
* @param url
* @param htmlFile
*/
const uploadHtml = (url, htmlFile) => {
// Content-Type は asset 作成時の mediaType パラメータ('text/html')と一致させる必要がある
// body に QfileView をセットすると Content-Type に charset が追加されてしまうため、ByteArrayWrapper をセット
const response = httpClient.begin()
.body(fileRepository.readFile(htmlFile), 'text/html')
.put(url);
const status = response.getStatusCode();
if (status !== 200) {
engine.log(response.getResponseAsString());
throw `Failed to upload HTML. status: ${status}`;
}
};
/**
* HTML から PDF を生成
* @param authSetting
* @param assetID
* @param pageSize
*/
const htmlToPdf = (authSetting, assetID, pageSize) => {
const body = JSON.stringify({
assetID,
json: '{}',
includeHeaderFooter: false,
pageLayout: LAYOUTS[pageSize]
});
const response = httpClient.begin().authSetting(authSetting)
.header('x-api-key', authSetting.getClientId())
.body(body, 'application/json')
.post('https://pdf-services-ue1.adobe.io/operation/htmltopdf');
const status = response.getStatusCode();
if (status !== 201) {
engine.log(response.getResponseAsString());
throw `Failed to convert HTML to PDF. status: ${status}`;
}
return response.getHeaderValues('Location').get(0);
};
/**
* PDF 生成のステータスを確認し、完了していればファイルを保存
* 処理途中であれば false を返す
* @param authSetting
* @param statusUrl
* @param pdfDef
* @param deleteOtherFiles
* @param fileName
* @returns {boolean|undefined} 処理途中であれば false
*/
const checkStatusAndSaveFile = (authSetting, statusUrl, pdfDef, deleteOtherFiles, fileName) => {
const {status, asset: {downloadUri} = {}, error = {}} = getStatus(authSetting, statusUrl);
switch (status) {
case 'done':
break;
case 'in progress':
return false;
case 'failed':
engine.log(JSON.stringify(error));
throw 'Failed to convert HTML to PDF.';
default:
throw `The converting status "${status}" is unknown.`;
}
const qfile = downloadPdf(downloadUri, fileName);
saveFile(pdfDef, deleteOtherFiles, qfile);
};
/**
* 変換ステータスを取得
* @param authSetting
* @param statusUrl
* @returns {Object}
*/
const getStatus = (authSetting, statusUrl) => {
const response = httpClient.begin().authSetting(authSetting)
.header('x-api-key', authSetting.getClientId())
.get(statusUrl);
const status = response.getStatusCode();
const respStr = response.getResponseAsString();
if (status !== 200) {
engine.log(respStr);
throw `Failed to get converting status. status: ${status}`;
}
return JSON.parse(respStr);
};
/**
* PDF ファイルのダウンロード
* @param downloadUrl
* @param fileName
*/
const downloadPdf = (downloadUrl, fileName) => {
const response = httpClient.begin().get(downloadUrl);
const status = response.getStatusCode();
if (status !== 200) {
engine.log(response.getResponseAsString());
throw `Failed to download PDF. status: ${status}`;
}
const qfile = new com.questetra.bpms.core.event.scripttask.NewQfile(
fileName, 'application/pdf', response.getResponse()
);
return qfile;
};
/**
* ファイルを保存
* @param dataDef
* @oaram deleteOtherFiles
* @param qfile
*/
const saveFile = (dataDef, deleteOtherFiles, qfile) => {
let files = engine.findData(dataDef);
if (files === null || deleteOtherFiles) {
files = new java.util.ArrayList();
}
files.add(qfile);
engine.setData(dataDef, files);
};