1

I have a webpage where I display a map using openstreetmap's ol3 library and other elements from primefaces:

<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui">
    <ui:define name="title"></ui:define>
    <ui:define name="content" style="border-style: none;">
    <script type="text/javascript" src="resources/js/ol.js"></script>
    <script type="text/javascript" src="resources/js/map.js"></script>
    <p:layoutUnit>
      <p:messages id="messages" showDetail="true" autoUpdate="true" closable="true"/>
      <h:form id="mainForm">
        <!--content-->
        <p:commandButton value="Build PDF" class="buttonFont" process="@all" actionListener="#{bean.createPDF}"     ajax="false"/>
      </h:form>  
    </p:layoutUnit>
     <p:layoutUnit position="center">
     <h:panelGroup  layout="block" id="map">
     </h:panelGroup>  

Script map.js:

var map; 
var osmlayer = new ol.layer.Tile({
            source: new ol.source.OSM()
        });

 var position = ol.proj.transform([longitude, latitude], 'EPSG:4326', 'EPSG:3857');
        var  view = new ol.View({
            center : position,
                    zoom : 12 

map = new ol.Map({
                target : document.getElementById('map'),
                layers : [osmlayer],
                controls : [ new ol.control.Zoom(), new ol.control.ScaleLine({
                    geodesic : true
                }), new ol.control.Attribution(), new ol.control.Rotate() ],
                view : view
            }); 

I need to get an image(png/jpeg) from what's been displayed on my map and add it to a new PDF generated by itextpdf in the current ManagedBean:

@ManagedBean(name = "bean")
@ViewScoped
public class mapBean{

    public void createPDF(){
        Document document = new Document(PageSize.A4, 50, 50, 50, 50);
        ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
        ec.setResponseHeader("Content-Type", "application/pdf");
        ec.setResponseHeader("Content-Disposition", "attachment; filename=\"Title.pdf\"");
        try{
           PdfWriter writer = PdfWriter.getInstance(document,ec.getResponseOutputStream());
           document.open();
           Image mapPDF = Image.getInstance(/*Set image from map*/);
           mapaPDF.scaleToFit(450,200);
           document.add(mapaPDF);
           document.close();
           FacesContext.getCurrentInstance().responseComplete();
        }
        catch (Exception er) {
        // TODO Auto-generated catch block
        er.printStackTrace();
        }
    }
}
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Cris P.
  • 11
  • 3

2 Answers2

0

You dont need to do it on the server side. You can just do it on the client side.

check this example

You can get the map image out of the canvas using canvas.toDataURL('image/jpeg');

pavlos
  • 3,001
  • 18
  • 23
  • It is indeed a good alternative if your familiar with the JavaScript PDF generation – Cris P. May 11 '16 at 15:46
  • if not use the `canvas.toDataURL('image/jpeg');` to generate your image and then you may send this to the technology you are familiar with and generate your pdf (like java itext etc) – pavlos May 11 '16 at 19:20
0

In javascript, I created a function to get the canvas of the map and insert it into an h:inputHidden :

function imagePDF(){
            canvas = document.getElementsByTagName('canvas')[0];
            var imagen = canvas.toDataURL('image/png');
            document.getElementById('mainForm:imagen').value = imagen;
        }

I call this function inside the p:commandButton :

<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui">
    <ui:define name="title"></ui:define>
    <ui:define name="content" style="border-style: none;">
    <script type="text/javascript" src="resources/js/ol.js"></script>
    <script type="text/javascript" src="resources/js/map.js"></script>
<p:layoutUnit>
      <p:messages id="messages" showDetail="true" autoUpdate="true" closable="true"/>
      <h:form id="mainForm">
        <h:inputHidden id="imagen" value="#{reporteController.imagen}" />
        <!--content-->
        <p:commandButton value="Build PDF" class="buttonFont" process="@all,mainForm:imagen" onclick="imagePDF();" actionListener="#{bean.createPDF}" ajax="false"/>
      </h:form>  
    </p:layoutUnit>
     <p:layoutUnit position="center">
     <h:panelGroup  layout="block" id="map">
     </h:panelGroup>  

And in the ManagedBean I retrieve the content of the h:inputHiddenand proceed with the decoding process of the canvas and get a byte array, which I can insert into the PDF:

@ManagedBean(name = "bean")
@ViewScoped
public class mapBean{

    public String getImagen() {
        return imagen;
    }

    public void setImagen(String imagen) {
        this.imagen = imagen;
    }

    public void createPDF(){
        Document document = new Document(PageSize.A4, 50, 50, 50, 50);
        ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
        ec.setResponseHeader("Content-Type", "application/pdf");
        ec.setResponseHeader("Content-Disposition", "attachment; filename=\"Title.pdf\"");
        try{
           PdfWriter writer = PdfWriter.getInstance(document,ec.getResponseOutputStream());
           document.open();
           BASE64Decoder decoder = new BASE64Decoder();
            byte[] decodedBytes = decoder.decodeBuffer(getImagen().split("^data:image/(png|jpg);base64,")[1]);
           Image mapPDF = Image.getInstance(decodedBytes);
           mapaPDF.scaleToFit(450,200);
           document.add(mapaPDF);
           document.close();
           FacesContext.getCurrentInstance().responseComplete();
        }
        catch (Exception er) {
        // TODO Auto-generated catch block
        er.printStackTrace();
        }
    }
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Cris P.
  • 11
  • 3