package x.y.z; import java.io.File; import org.apache.log4j.Logger; import org.htmlcleaner.CleanerProperties; import org.htmlcleaner.HtmlCleaner; import org.htmlcleaner.PrettyXmlSerializer; import org.htmlcleaner.TagNode; import com.appiancorp.suiteapi.common.Name; import com.appiancorp.suiteapi.content.ContentConstants; import com.appiancorp.suiteapi.content.ContentService; import com.appiancorp.suiteapi.knowledge.Document; import com.appiancorp.suiteapi.knowledge.DocumentDataType; import com.appiancorp.suiteapi.knowledge.FolderDataType; import com.appiancorp.suiteapi.process.exceptions.SmartServiceException; import com.appiancorp.suiteapi.process.framework.AppianSmartService; import com.appiancorp.suiteapi.process.framework.Input; import com.appiancorp.suiteapi.process.framework.MessageContainer; import com.appiancorp.suiteapi.process.framework.Required; import com.appiancorp.suiteapi.process.framework.SmartServiceContext; import com.appiancorp.suiteapi.process.palette.PaletteInfo; import java.io.FileOutputStream; import java.io.StringReader; import com.itextpdf.text.PageSize; import com.itextpdf.text.pdf.PdfWriter; import com.itextpdf.tool.xml.XMLWorkerHelper; @PaletteInfo(paletteCategory = "Custom Services", palette = "XYZServices") public class RenderHtmlToPdf extends AppianSmartService { private static final Logger LOG = Logger.getLogger(RenderHtmlToPdf.class); private final SmartServiceContext smartServiceCtx; private final ContentService contentService; private String html_string; private Long pdf_folder; private Long pdf_document; private String pdf_name; @Override public void run() throws SmartServiceException { Document appianDocument = null; Long documentId = null; String target_pathname = null; try { // Create the new Appian document. Then set the status of the document. appianDocument = new Document(pdf_folder, pdf_name , "pdf"); appianDocument.setState(ContentConstants.STATE_PUBLISHED); // Attempt to create the document in Appian using the Content Service documentId = contentService.create(appianDocument, ContentConstants.UNIQUE_NONE); // Set the "pdf_document" ARV to the documentID of the new document created pdf_document = documentId; //LOG.error("Created document with ID " + documentId.toString()); // Get local filepath on Appian server where physical file was created target_pathname = contentService.getInternalFilename(documentId).replace('\\','/'); //LOG.error(target_pathname); // Clean up the HTML as itext requires valid XHTML CleanerProperties props = new CleanerProperties(); TagNode tagNode = new HtmlCleaner(props).clean(html_string); html_string = new PrettyXmlSerializer(props).getAsString(tagNode); com.itextpdf.text.Document itDocument = new com.itextpdf.text.Document(PageSize.A4); PdfWriter pdfWriter = PdfWriter.getInstance(itDocument, new FileOutputStream(target_pathname)); itDocument.open(); try { itDocument.addCreationDate(); XMLWorkerHelper.getInstance().parseXHtml(pdfWriter, itDocument, new StringReader(html_string)); } catch (Exception e) { LOG.error("Error rendering document", e); } finally { itDocument.close(); } //create a new version of AE doc to set size appianDocument = (com.appiancorp.suiteapi.knowledge.Document)contentService.getVersion(documentId, ContentConstants.VERSION_CURRENT); File newFile = new File(target_pathname); appianDocument.setSize(new Integer((int) newFile.length())); contentService.createVersion(appianDocument, ContentConstants.UNIQUE_NONE); } catch (Exception e) { LOG.error("Error rendering document", e); } } public RenderHtmlToPdf(SmartServiceContext smartServiceCtx, ContentService cs) { super(); this.smartServiceCtx = smartServiceCtx; this.contentService = cs; } public void onSave(MessageContainer messages) { } public void validate(MessageContainer messages) { } @Input(required = Required.ALWAYS) @Name("html_string") public void setHtml_string(String val) { this.html_string = val; } @Name("pdf_document") @DocumentDataType public Long getPdf_document() { return pdf_document; } @Input(required = Required.ALWAYS) @Name("pdf_folder") @FolderDataType public void setPdf_folder(Long val) { this.pdf_folder = val; } @Input(required = Required.ALWAYS) @Name("pdf_name") public void setPdf_name(String val) { this.pdf_name = val; } }