Quantcast
Channel: Experiencing Adobe Experience Manager (AEM, CQ)
Viewing all articles
Browse latest Browse all 525

AEM 61 - Add "Save as PDF" button to the Assets Console Action bar

$
0
0

Goal


In DAM Assets console of Touch UI, add button Save as PDF to the Action Bar for downloading selected assets as PDF

Demo | Package Install | Source Code


Save as PDF button added to Action Bar



Downloaded PDF

 


Solution


1) Create a OSGI servlet apps.experienceaem.assets.CreatePDFFromAssetsServlet in CRX folder /apps/eaem-save-assets-as-pdf with the following code

package apps.experienceaem.assets;

import com.adobe.internal.io.ByteWriter;
import com.adobe.internal.io.RandomAccessFileByteWriter;
import com.adobe.internal.pdftoolkit.core.types.ASMatrix;
import com.adobe.internal.pdftoolkit.pdf.document.PDFDocument;
import com.adobe.internal.pdftoolkit.pdf.document.PDFOpenOptions;
import com.adobe.internal.pdftoolkit.pdf.document.PDFSaveFullOptions;
import com.adobe.internal.pdftoolkit.pdf.graphics.PDFExtGState;
import com.adobe.internal.pdftoolkit.pdf.graphics.PDFRectangle;
import com.adobe.internal.pdftoolkit.pdf.graphics.xobject.PDFXObjectImage;
import com.adobe.internal.pdftoolkit.pdf.page.PDFPage;
import com.adobe.internal.pdftoolkit.pdf.page.PDFPageTree;
import com.adobe.internal.pdftoolkit.services.imageconversion.ImageManager;
import com.day.cq.dam.api.Asset;
import com.day.cq.dam.api.AssetManager;
import com.day.cq.dam.commons.util.DamUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import javax.jcr.Node;
import javax.servlet.ServletException;
import java.awt.image.BufferedImage;
import java.io.*;

@Component(metatype = true, label = "Experience AEM Create PDF From Assets", description = "")
@Service
@Properties({
@Property(name = "sling.servlet.methods", value = {"GET" }, propertyPrivate = true),
@Property(name = "sling.servlet.paths", value = "/bin/eaem/createpdf", propertyPrivate = true)})
public class CreatePDFFromAssetsServlet extends SlingAllMethodsServlet {
private static final Logger log = LoggerFactory.getLogger(CreatePDFFromAssetsServlet.class);

protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)
throws ServletException, IOException {
try{
String assetPaths = request.getParameter("assetPaths");

if(StringUtils.isEmpty(assetPaths)){
response.getWriter().print("No asset paths provided");
}else{
Asset pdf = createPDF(assetPaths, request);

if(pdf == null){
response.getWriter().print("Error creating pdf");
}else{
writePDF(response, pdf);
}
}
}catch(Exception e){
log.error("Error creating pdf", e);
}
}

private void writePDF(SlingHttpServletResponse response, Asset pdf) throws Exception{
response.setContentType("application/pdf");
response.addHeader("Content-Disposition", "attachment; filename=" + pdf.getName());
response.setContentLength((int)pdf.getOriginal().getSize());

InputStream is = null;

try{
is = pdf.getOriginal().getStream();
OutputStream responseOutputStream = response.getOutputStream();
int bytes;

while ((bytes = is.read()) != -1) {
responseOutputStream.write(bytes);
}
}finally{
if(is != null){
is.close();
}
}
}

private Asset createPDF(String assetPaths, SlingHttpServletRequest request) throws Exception{
String pdfPath = null;
File tmpFile = null;
ByteWriter tmpFileWriter = null;

FileInputStream tmpFileReader = null;
Asset asset = null, pdf = null;
ResourceResolver resolver = request.getResourceResolver();

PDFDocument pdfDocument = null;
InputStream assetStream = null;

try{
Node folder = null;

pdfDocument = PDFDocument.newInstance(PDFOpenOptions.newInstance());
PDFPageTree pageTree = pdfDocument.requireCatalog().getPages();

for(String assetPath : assetPaths.split(",")){
asset = DamUtil.resolveToAsset(resolver.getResource(assetPath));

if(folder == null){
folder = asset.adaptTo(Node.class).getParent();
}

assetStream = asset.getOriginal().getStream();

BufferedImage bImage = ImageIO.read(assetStream);

PDFXObjectImage image = ImageManager.getPDFImage(bImage, pdfDocument);

PDFPage newPage = PDFPage.newInstance(pdfDocument,
PDFRectangle.newInstance(pdfDocument,0, 0, image.getWidth(), image.getHeight()));

ImageManager.insertImageInPDF(image, newPage,
PDFExtGState.newInstance(pdfDocument),
new ASMatrix(image.getWidth(), 0, 0, image.getHeight(), 0, 0));

if (pageTree == null){
pageTree = PDFPageTree.newInstance(pdfDocument, newPage);
}else{
pageTree.getPage(0).prependPage(newPage);
}

assetStream.close();
}

tmpFile = File.createTempFile(folder.getName(), ".pdf");

tmpFileWriter = getTempFileWriter(tmpFile);

pdfDocument.save(tmpFileWriter, PDFSaveFullOptions.newInstance());

tmpFileReader = new FileInputStream(tmpFile);

AssetManager assetMgr = resolver.adaptTo(AssetManager.class);

pdfPath = folder.getPath() + "/" + folder.getName() + ".pdf";

Resource resource = resolver.getResource(pdfPath);

if(resource != null){
resource.adaptTo(Node.class).remove();
}

pdf = assetMgr.createAsset( pdfPath, tmpFileReader, "application/pdf", true);
}catch(Exception e){
log.warn("Error generating pdf", e);
}finally{
if(assetStream != null){
assetStream.close();
}

if (pdfDocument != null) {
pdfDocument.close();
}

if (tmpFileWriter != null) {
tmpFileWriter.close();
}

if(tmpFileReader !=null ){
tmpFileReader.close();
}
}

return pdf;
}

private ByteWriter getTempFileWriter(File file) throws IOException {
file.delete();

File parent = file.getParentFile();

if (parent != null) {
parent.mkdirs();
}

file.createNewFile();

return new RandomAccessFileByteWriter(new RandomAccessFile(file, "rw"));
}
}


2) For compilation, Gibson libraries (com.adobe.internal.pdftoolkit) are not available on Adobe public maven repo Nexus; so create a private repo - eaemrepo and add the location in repositories section of project pom.xml (the jars can be found in CQ install eg. author\crx-quickstart\launchpad\felix\bundle446\data\install\pdfcore-3.0.568820.jar or you can get them from this sample's source code)

<repositories>
<repository>
<id>eaemrepo</id>
<name>Experience AEM Internal Repo</name>
<url>file://${project.basedir}/../libs</url>
</repository>
<repository>
<id>adobe</id>
<name>Adobe Public Repository</name>
<url>http://repo.adobe.com/nexus/content/groups/public/</url>
<layout>default</layout>
</repository>
</repositories>

        jars added in eaemrepo

 

3) Create a clientlib (type cq:ClientLibraryFolder) /apps/eaem-save-assets-as-pdf/clientlib with categories - cq.gui.damadmin.admin

4) Create file /apps/eaem-save-assets-as-pdf/clientlib/js.txt with the following content

                                                save-as-pdf.js

5) Create file /apps/eaem-save-assets-as-pdf/clientlib/save-as-pdf.js with the following code

(function ($, $document) {
var DOWNLOAD_ACTIVATOR = "cq-damadmin-admin-actions-download-activator",
TEXT = "Save as PDF",
CREATE_PDF_URL = "/bin/eaem/createpdf?assetPaths=",
added = false;

$document.on("foundation-mode-change", addButton);

function addButton(e, mode){
if(added || (mode !== "selection") ){
return;
}

added = true;

var $cFolder = $("." + DOWNLOAD_ACTIVATOR);

if ($cFolder.length == 0) {
return;
}

var $downloadPdf = $cFolder.after($($cFolder[0].outerHTML));

$downloadPdf.attr("title", TEXT)
.removeClass(DOWNLOAD_ACTIVATOR)
.removeAttr("href")
.click(downloadPDF)
.find("span").html(TEXT);

$document.on("foundation-selections-change", ".foundation-collection", function() {
var $selectedItems = $(".foundation-selections-item");

if($selectedItems.length > 0){
$downloadPdf.removeAttr("hidden");
}
});

function downloadPDF() {
var $items = $(".foundation-selections-item"),
assetPaths = [];

$items.each(function () {
assetPaths.push($(this).data("path"));
});

window.open(CREATE_PDF_URL + assetPaths.join(","), "_blank");
}
}
})(jQuery, jQuery(document));


Viewing all articles
Browse latest Browse all 525

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>