javajasper-reportsexport-to-pdfjaspersoft-studio

How to fix "No generic element handlers found for namepsace" error in case using custom genericElement?


I am trying to adapted the example of jasper reports to customized a generic element with a HTML handler to an Example with a PDF handler. But I got all the time the same error message, when trying to run the

net.sf.jasperreports.engine.JRRuntimeException: No generic element handlers found for namespace http://jasperreports.sourceforge.net/jasperreports/customPDFexpoter.
at net.sf.jasperreports.engine.export.GenericElementHandlerEnviroment.getElementHandler(GenericElementHandlerEnviroment.java:112)
at net.sf.jasperreports.engine.export.JRPdfExporter.exportGenericElement(JRPdfExporter.java:4136)
at net.sf.jasperreports.engine.export.JRPdfExporter.exportElements(JRPdfExporter.java:1290)
at net.sf.jasperreports.engine.export.JRPdfExporter.exportPage(JRPdfExporter.java:1210)
at net.sf.jasperreports.engine.export.JRPdfExporter.exportReportToStream(JRPdfExporter.java:1074)
at net.sf.jasperreports.engine.export.JRPdfExporter.exportReport(JRPdfExporter.java:691)
at com.jaspersoft.studio.editor.preview.actions.export.AExportAction.exportWithProgress(AExportAction.java:223)
at com.jaspersoft.studio.editor.preview.actions.export.AExportAction.doPreview(AExportAction.java:347)
at com.jaspersoft.studio.editor.preview.actions.export.AExportAction$3.run(AExportAction.java:191)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)

Also I've followed this example how to embedd a controller to a PDF, without success. Also there the namespace can't be found. Did I miss something in the project configuration?

here is my JRXML:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.14.0.final using JasperReports Library version 6.14.0-2ab0d8625be255bf609c78e1181801213e51db8f  -->
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="Blank_A4" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="c685fd77-7e9f-4762-9a4a-422d1c15aed0">
    <property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
    <queryString>
        <![CDATA[]]>
    </queryString>
    <background>
        <band splitType="Stretch"/>
    </background>
    <title>
        <band height="500" splitType="Stretch">
            <property name="com.jaspersoft.studio.unit.height" value="px"/>
            <genericElement>
                <reportElement x="94" y="93" width="236" height="107" uuid="0dbdbc2d-cead-47eb-8605-e18cc325259a"/>
                <genericElementType namespace="http://jasperreports.sourceforge.net/jasperreports/customPDFexpoter" name="print"/>
            </genericElement>
        </band>
    </title>
</jasperReport>

My jasperreports_extension.properties (inside src-Folder)

net.sf.jasperreports.extension.registry.factory.jr.statistics=net.sf.jasperreports.extensions.SpringExtensionsRegistryFactory
net.sf.jasperreports.extension.jr.statistics.spring.beans.resource=com/test/beans.xml

The beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="pdfExportHandlerBundle" 
        class="net.sf.jasperreports.engine.export.DefaultElementHandlerBundle">
    <property name="namespace" value="http://jasperreports.sourceforge.net/jasperreports/customPDFexpoter"/>
    <property name="elementHandlers">
        <map>
            <entry key="print">
                <map>
                    <entry key="net.sf.jasperreports.pdf">
                        <ref bean="basePdfExportHandler"/>
                    </entry>
                </map>
            </entry>
        </map>
    </property>
</bean>
<bean id="basePdfExportHandler" class="com.test.TestPDFHandler"
        abstract="true">
</bean>

The Java-File (src/com/test)

package com.test;

import net.sf.jasperreports.engine.JRGenericPrintElement;
import net.sf.jasperreports.engine.JRPropertiesMap;
import net.sf.jasperreports.engine.JRRuntimeException;
import net.sf.jasperreports.engine.export.GenericElementHandler;
import net.sf.jasperreports.engine.export.GenericElementHandlerBundle;
import net.sf.jasperreports.engine.export.GenericElementPdfHandler;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.export.JRPdfExporterContext;
import net.sf.jasperreports.extensions.ExtensionsRegistry;
import net.sf.jasperreports.extensions.ExtensionsRegistryFactory;
import net.sf.jasperreports.extensions.SingletonExtensionRegistry;

import com.lowagie.text.Chunk;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Phrase;
import com.lowagie.text.pdf.ColumnText;
import com.lowagie.text.pdf.PdfAction;

public class TestPDFHandler implements GenericElementPdfHandler {

@Override
public boolean toExport(JRGenericPrintElement element) {
    return true;
}

@Override
public void exportElement(JRPdfExporterContext exporterContext,
        JRGenericPrintElement element) {
    Phrase phrase = new Phrase();
    Chunk chunk = new Chunk("print me");
    chunk.setAction(PdfAction.javaScript("this.print(null,this.pageNum,this.pageNum)", exporterContext.getPdfWriter()));
    phrase.add(chunk);

    ColumnText colText = new ColumnText(exporterContext.getPdfWriter().getDirectContent());
    colText.setSimpleColumn(phrase, 
            element.getX(), 
            exporterContext.getExportedReport().getPageHeight() - element.getY(),
            element.getX() + element.getWidth(), 
            exporterContext.getExportedReport().getPageHeight() - element.getY() - element.getHeight(), 
            0, 
            Element.ALIGN_LEFT);

    try {
        colText.go();
    } catch (DocumentException e) {
        throw new JRRuntimeException(e);
    }

}
/*
@Override
public String getNamespace() {
    return "helloWorld";
}

@Override
public GenericElementHandler getHandler(String elementName, String exporterKey) {
    if (elementName.equals("print") && exporterKey.equals(JRPdfExporter.PDF_EXPORTER_KEY)) {
        return this;
    }
    
    return null;
}

@Override
public ExtensionsRegistry createRegistry(String registryId, JRPropertiesMap properties) {
    return new SingletonExtensionRegistry<GenericElementHandlerBundle>(GenericElementHandlerBundle.class, this);
}*/
}

Solution

  • You need to register it as a factory in jasperreports_extension.properties add

    net.sf.jasperreports.extension.registry.factory.me=com.test.TestPDFHandler
    

    When this is done, then you need to implement the interface that are missing in your TestPDFHandler and getNamespace() needs to correspond with the namespace that you have given to the genericElementType*

    public class TestPDFHandler implements GenericElementPdfHandler, GenericElementHandlerBundle, ExtensionsRegistryFactory {
    
        @Override
        public boolean toExport(JRGenericPrintElement element) {
            return true;
        }
    
        @Override
        public void exportElement(JRPdfExporterContext exporterContext,
                JRGenericPrintElement element) {
            Phrase phrase = new Phrase();
            Chunk chunk = new Chunk("print me");
            chunk.setAction(PdfAction.javaScript("this.print(null,this.pageNum,this.pageNum)", exporterContext.getPdfWriter()));
            phrase.add(chunk);
    
            ColumnText colText = new ColumnText(exporterContext.getPdfWriter().getDirectContent());
            colText.setSimpleColumn(phrase,
                    element.getX(),
                    exporterContext.getExportedReport().getPageHeight() - element.getY(),
                    element.getX() + element.getWidth(),
                    exporterContext.getExportedReport().getPageHeight() - element.getY() - element.getHeight(),
                    0,
                    Element.ALIGN_LEFT);
    
            try {
                colText.go();
            } catch (DocumentException e) {
                throw new JRRuntimeException(e);
            }
    
        }
    
        @Override
        public String getNamespace() {
            return "http://jasperreports.sourceforge.net/jasperreports/customPDFexpoter";
        }
    
        @Override
        public GenericElementHandler getHandler(String elementName, String exporterKey) {
            if (elementName.equals("print") && exporterKey.equals(JRPdfExporter.PDF_EXPORTER_KEY)) {
                return this;
            }
    
            return null;
        }
    
        @Override
        public ExtensionsRegistry createRegistry(String registryId, JRPropertiesMap properties) {
            return new SingletonExtensionRegistry<GenericElementHandlerBundle>(GenericElementHandlerBundle.class, this);
        }
    }
    

    *You can indicate whatever namespace, I would not use http://jasperreports.sourceforge.net/jasperreports/customPDFexpoter since it's not my domain but to follow your code it is used in example below