2009-11-20 13 views
10

Estoy creando un programa de informes simple usando java e iReport (de jasper), que se supone que crea un informe en pdf que muestra las PC con su dirección IP, su ubicación, si está inactivo o no en este momento (manejado por otro sistema), y una lista de proyectos a los que actualmente está asociado (administrado en otro lugar, también).¿Cómo imprimo una lista de cadenas contenidas dentro de otra lista en iReport?

estoy usando iReport para este asunto, y he creado una clase de generación de recogida maniquí de la siguiente manera:

public class PCReports { 

    public static java.util.Collection PC_collection; 
    public static java.util.Collection generateCollection() { 

     PC_collection = new ArrayList<PCLineDTO>(); 
     PCLineDTO line = new PCLineDTO(); 
     line.setIP("192.168.1.1"); 
     line.setLab("location"); 
     line.setActive(true); 
     line.addProjectName("project1"); 
     line.addProjectName("project2"); 
     line.addProjectName("project3"); 
     PC_collection.add(line); 

     line = new PCLineDTO(); 
     line.setIp("192.168.1.2"); 
     line.setLab("location2"); 
     line.setActive(false); 
     line.addProjectName("project1"); 
     line.addProjectName("project2"); 
     PC_collection.add(line); 

     return PC_collection; 
    } 
} 

La clase de entidad en este caso ser:

public class PCLineDTO { 
    private String ip; 
    private String lab; 
    private Boolean active; 
    private ArrayList<String> projects; 
} 

Después de buscar alrededor Internet, encontré a way to do something similar, usando subinformes.

La cuestión es que no sé cómo imprimir una colección de cadenas pasadas como dataSource a este subinforme.

En los ejemplos que encontré en Internet, para cada elemento de la colección principal, los informes integrados se aprobaron una colección de objetos -con sus propios métodos de acceso para cada atributo, en lugar de una colección de cadenas como es el caso aquí. En esos casos, se accede a los valores que necesitan para utilizar a través de la sintaxis iReport, que no era capaz de utilizar, por ejemplo:

$F{project} 

Desde iReport busca un método getProject contenida dentro de los objetos que recibe, pero en este caso, es un objeto String simple (sin un método getProject, por así decirlo).

+0

¿Qué versión de JasperReport/iReport estás usando? – medopal

+0

@medopal: Afortunadamente, la última (en el momento de esta publicación: 3.6.1). –

Respuesta

17

Use un subinforme o un subdataset.

Pase el subinforme una fuente de datos recogida

JRBeanCollectionDataSource($F{Projects}) 

Luego, en el nuevo informe integrado crear un nuevo campo llamado "_Es" exactamente, esto significa que el grano de la colección pasado es el mismo que el valor que quiero

Para obtener más información, compruebe el código fuente de la clase aquí: JRAbstractBeanDataSource

Nota: esto está disponible en JasperReport 3.0.0 no estoy seguro de si existe en la acumulación previa s. Esperanza esto ayuda

actualización: acaba de comprobar la SVN, parece que esta característica se implementa en JasperReports 2.0.0

+1

Gracias, me alegro de que haya ayudado. Solo una nota al margen, cuando trato con Jasper o cualquier otro proyecto de código abierto, tiendo a extraer el código fuente y adjuntarlo a la biblioteca en Eclipse. De esta manera es más fácil cavar dentro. Buena suerte – medopal

+0

He encontrado detalles complementarios aquí: http://community.jaspersoft.com/questions/533552/solved-problem-passing-datasource-subreport –

3

Interesante. Creo que será mejor que uses la Lista y luego defines getName() en la clase Project. Luego, en el informe integrado, defina una variable "nombre". Funcionará de esta manera y le permitirá agregar fácilmente información adicional, como duración del proyecto, liderazgo de equipo, etc.

+0

Gracias por su respuesta. Consideré esto y podría implementarlo de esta manera, si las cosas llegan a eso. Sin embargo, lamentablemente (y reconozco que es mi culpa), otras partes del programa están usando esta lista de cadenas, y me preguntaba si había una forma de eludir la tarea problemática y propensa a errores de buscar y reemplazar donde se ha utilizado. –

0

Como dice Bozho, en caso de proyects era una gran variedad de objetos complejos que debe hacer referencia a ella como un campo de tipo java.util.Collection y luego pasarlo al subinforme interno de la misma manera que lo indica medopal. Y no pongas el campo _THIS.

0

Para profundizar en esto sin usar _THIS: digamos que un java tiene una lista de subBeans y este subBean tiene un formato complejo y queremos imprimir cada subBean de manera personalizada. Cito un ejemplo donde el elemento subdataset está en el nivel de informe y el componentElement está en la banda de detalle:

<subDataset name="ListOfSubBeans" uuid="66c86e41-c565-4f18-bccf-1a1b2a567585"> 
    <field name="subBeanField_1" class="java.lang.String"> 
     <fieldDescription><![CDATA[subBeanField_1]]></fieldDescription> 
    </field> 
</subDataset> 

... 

     <componentElement> 
      <reportElement x="780" y="0" width="100" height="30" uuid="f73864b9-46dd-4adb-8dad-a6bd8dfae64e"> 
       <property name="net.sf.jasperreports.export.headertoolbar.table.name" value=""/> 
      </reportElement> 
      <jr:list xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd" printOrder="Vertical"> 
       <datasetRun subDataset="ListOfSubBeans" uuid="a8dd1c2b-3ac0-4ffa-b9d0-08e4890e199a"> 
        <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{listOfSubBeans})]]></dataSourceExpression> 
       </datasetRun> 
       <jr:listContents height="30" width="100"> 
        <textField> 
         <reportElement x="0" y="0" width="100" height="30" uuid="61700c18-6bb9-45da-a235-b76b9f76a2ea"/> 
         <textFieldExpression><![CDATA[$F{subBeanField_1}]]></textFieldExpression> 
        </textField> 
       </jr:listContents> 
      </jr:list> 
     </componentElement> 

... 

Por lo tanto, el conjunto de datos maestro ha declarado que el grano principal tiene una variable miembro que es una lista: listOfSubBeans . Este java.util.List se utiliza para alimentar el origen de datos del jr:list, mientras que los campos del jr:list se declaran utilizando un subDataset llamado ListOfSubBeans (preste atención a la distinción entre mayúsculas y minúsculas).

Cuestiones relacionadas