web

[Java] Membuat Laporan Excel di Aplikasi Web Based

Excel adalah salah satu format output yang disukai oleh enduser, selain dari pdf. Karena di excel pengguna bisa melakukan perhitungan-perhitungan, modifikasi ataupun kustomisasi yang lebih bebas dibandingkan dari pdf.

Di tutorial ini, akan dibahas bagaimana membuat export laporan aplikasi web-based ke format xls. Gw menggunakan library jxls (http://jxls.sourceforge.net/) karena lebih mudah dalam pembuatan format template excel jika dibandingkan dengan jasper. Konsepnya sebenarnya sederhana, sebuah servlet yang jika diinvoke dari method GET, akan meng-generate file excel dan mengirimkan ke pengguna langsung via browser.

Dimulai dengan membuat template excel yang akan kita isi dengan data (perhatikan baris ke-5), kemudian diletakkan dibawah folder WEB-INF.

Untuk sourcecodenya seperti biasa, sebuah java bean sederhana sebagai tempat untuk menampung data

package com.edw.bean;

public class Mahasiswa {

    private String nama;
    private String alamat;
    private int usia;

	// jangan lupa setter dan getter-nya    
}

Berikut adalah servlet yang digunakan untuk meng-generate laporan berformat xcel

package com.edw.servlet;

import com.edw.bean.Mahasiswa;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.jxls.transformer.XLSTransformer;
import org.apache.poi.ss.usermodel.Workbook;

public class ReportServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        // set output header
        ServletOutputStream os = response.getOutputStream();
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-Disposition", "attachment; filename=\"report." + new SimpleDateFormat("yyyyMMdd.hhmm").format(new Date()) + ".xls\"");

        // ambil file excelnya
        ServletContext context = getServletContext();
        String reportLocation = context.getRealPath("WEB-INF");

        // buat data
        List<Mahasiswa> mahasiswas = new ArrayList<Mahasiswa>();
        for (int i = 0; i < 10; i++) {
            Mahasiswa mahasiswa = new Mahasiswa();

            mahasiswa.setNama("Edwin " + new Random().nextInt());
            mahasiswa.setAlamat("Jakarta " + new Random().nextInt());
            mahasiswa.setUsia(new Random().nextInt());

            mahasiswas.add(mahasiswa);
        }

        // kirim ke excel
        Map beans = new HashMap();
        beans.put("x", mahasiswas);

        try {
            XLSTransformer transformer = new XLSTransformer();
            Workbook workbook = transformer.transformXLS(new FileInputStream(reportLocation + "/report.xls"), beans);
            workbook.write(os);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            os.flush();
        }
    }
}

Jangan lupa daftarkan servletnya di web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app  version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <display-name>Reporting Excel</display-name>

    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>  
    
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
	
    <servlet>
        <servlet-name>reportServlet</servlet-name>
        <servlet-class>com.edw.servlet.ReportServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>reportServlet</servlet-name>
        <url-pattern>/reportServlet</url-pattern>
    </servlet-mapping>	  

</web-app>

Kemudian file jsp yang akan dijadikan sebagai halaman landing page

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <h1>Download</h1>
        <a href="reportServlet">here</a>        
    </body>
</html>

Jika dijalankan, akan menghasilkan aplikasi web seperti ini,

Ini adalah isi file excel hasil download ketika dibuka

Berikut adalah konfigurasi dan library yang gw gunakan di Netbeans gw,

Ga terlalu sulit kan bikin laporan pakek JXLS 😉

[Java] How to Convert .csv to Shapefile shape format (.shp)?

On my previous project, i had a request to provide a csv to shp converter feature. After googling for a while, i found a simple java code snippet, i modified some of its part so i could integrate it on my GIS project and hope it will be more flexible.

This is part of inflasi3.csv file that will be converted into shp

KOTA,LAT,LON,JULIL2009,AGUS2009,9-Sep,OKT2009,9-Nov,DES2009,10-Jan,10-Feb,10-Mar,10-Apr,MEI2010,JUNI2010
BANDA ACEH,5.546181947,95.32366186,0.8,1.45,1.82,-1.3,0.45,-0.23,-0.3,-0.04,0.7,-0.47,0.63,0.63
TARAKAN,3.276090324,117.6193848,0.99,0.97,1.53,-0.74,0.64,1.76,0.24,0.2,0.08,0.09,-0.19,1.44
MANADO,1.493103951,124.8409503,0.46,0.65,-0.36,0.83,1.27,0.38,-1.35,1.25,1.29,-1.32,-0.64,-0.12

And this is my java class,

package com.baculsoft.main;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import org.geotools.data.DataStoreFactorySpi;
import org.geotools.data.DataUtilities;
import org.geotools.data.DefaultTransaction;
import org.geotools.data.FeatureStore;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureCollections;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;

public class Csv2Shape {

    public static void main(String[] args) throws Exception {
        File file = new File("inflasi3.csv");

        FeatureCollection<SimpleFeatureType, SimpleFeature> collection = FeatureCollections.newCollection();
        BufferedReader reader = new BufferedReader(new FileReader(file));
        SimpleFeatureType TYPE = null;
        try {
            String line = reader.readLine();
            
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("location:Point,");

            String[] headers = line.split("\\,"); 
            for (String header : headers) {
                stringBuilder.append("").append(header).append(":String,");
            }

            TYPE = DataUtilities.createType("Location", stringBuilder.substring(0, stringBuilder.toString().length() - 1));
            GeometryFactory factory = JTSFactoryFinder.getGeometryFactory(null);

            for (line = reader.readLine(); line != null; line = reader.readLine()) {
                String split[] = line.split("\\,");

                String name = split[0]; 
                double latitude = Double.parseDouble(split[1]);
                double longitude = Double.parseDouble(split[2]);

                Object[] o = new Object[split.length+1];
                for (int i = 2; i < o.length; i++) {
                    o[i] = split[i-1];
                }

                o[0] = factory.createPoint(new Coordinate(longitude, latitude));
                o[1] = name;

                SimpleFeature feature = SimpleFeatureBuilder.build(TYPE, o, null);
                collection.add(feature);
            }
        } finally {
            reader.close();
        }
        File newFile = new File("inflasi4.shp");

        DataStoreFactorySpi factory = new ShapefileDataStoreFactory();

        Map<String, Serializable> create = new HashMap<String, Serializable>();
        create.put("url", newFile.toURI().toURL());
        create.put("create spatial index", Boolean.TRUE);

        ShapefileDataStore newDataStore = (ShapefileDataStore) factory.createNewDataStore(create);
        newDataStore.createSchema(TYPE);
        newDataStore.forceSchemaCRS(DefaultGeographicCRS.WGS84);

        Transaction transaction = new DefaultTransaction("create");

        String typeName = newDataStore.getTypeNames()[0];
        FeatureStore<SimpleFeatureType, SimpleFeature> featureStore;
        featureStore = (FeatureStore<SimpleFeatureType, SimpleFeature>) newDataStore.getFeatureSource(typeName);

        featureStore.setTransaction(transaction);
        try {
            featureStore.addFeatures(collection);
            transaction.commit();
        } catch (Exception ex) {
            ex.printStackTrace();
            transaction.rollback();
        } finally {
            transaction.close();
        }
    }
}

And this is my pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.edw</groupId>
    <artifactId>CSV2SHP</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>CSV2SHP</name>
    <url>http://maven.apache.org</url>
    
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!-- use the latest snapshot -->
        <geotools.version>8.4</geotools.version>
    </properties>
  
    <repositories>
        <repository>
            <id>maven2-repository.dev.java.net</id>
            <name>Java.net repository</name>
            <url>http://download.java.net/maven/2</url>
        </repository>
        <repository>
            <id>osgeo</id>
            <name>Open Source Geospatial Foundation Repository</name>
            <url>http://download.osgeo.org/webdav/geotools/</url>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-shapefile</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-swing</artifactId>
            <version>${geotools.version}</version>
        </dependency>
    </dependencies>
</project>

This is the screenshot of my viewer (geoexplorer) after i uploaded inflasi4.shp, which is the result of converting inflasi3.csv
converting from csv to shp

Hope it helps other, have fun (H)

How to Fix WebSphere’s Failed to Start Service

Today im trying to start my IBM WebSphere from Windows Service, but it keeps showing error. And i cant even starting WebSphere from Command Prompt. This is the error on my WebSphere error log file.

[18/10/12 18:59:12:760 ICT] 00000000 WindowsServic 3   Timed out waiting for service to respond to command, after 60 seconds. Failed to start service, or timed out while waiting for start to complete. Check the logs for details.
[18/10/12 18:59:12:760 ICT] 00000000 AdminTool     A   ADMU7704E: Failed while trying to start the Windows Service associated with server: server1; 
probable error executing WASService.exe: Starting Service: XNode01
Timed out waiting for service to respond to command, after 60 seconds. Failed to start service, or timed out while waiting for start to complete. Check the logs for details.

How to fix it is actually not too hard, i just delete server1.pid which located under my WebSphere logs folder and start my WebSphere again. Somehow WebSphere wont start if server1.pid exists.

This is the location for my logs folder

C:\Program Files\IBM\WebSphere\AppServer\profiles\AppSrv01\logs\server1

Have fun (F)

Weird Error on Websphere : java.lang.NoClassDefFoundError: com.ibm.ws.management.configservice.TypeRegistry

I had a very weird error today on WebSphere, very weird because i never had this kind of error before. This error shows up on WebSphere administrative console. This is part of the error’s stacktrace.

An error occurred while processing request:
/ibm/console/secure/layouts/contentLayout.jsp

java.lang.NoClassDefFoundError: com.ibm.ws.management.configservice.TypeRegistry

How to remove is actually very easy, i just delete the tranlog folder on your Websphere folder. This is my complete path of tranlog folder.

C:\Program Files\IBM\WebSphere\AppServer\profiles\AppSrv01\tranlog

Hope it will help others, good luck 😉

Beginning Sitemesh

In this tutorial, im trying to create a simple application using Sitemesh. According to Wikipedia, Sitemesh is a web-page layout and decoration framework and web application integration framework to aid in creating large sites consisting of many pages for which a consistent look/feel, navigation and layout scheme is required. So basically, Sitemesh is a templating engine or a decorator pattern.

Let’s start with a simple application, first is a maven’s pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.edw</groupId>
    <artifactId>SitemeshExample</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>SitemeshExample Web App</name>

    <properties>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <netbeans.hint.deploy.server>Tomcat70</netbeans.hint.deploy.server>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>6.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8.1</version>
            <scope>test</scope>
        </dependency>
        
        <dependency>
            <groupId>opensymphony</groupId>
            <artifactId>sitemesh</artifactId>
            <version>2.4.2</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <compilerArguments>
                        <endorseddirs>${endorsed.dir}</endorseddirs>
                    </compilerArguments>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.1</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.1</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${endorsed.dir}</outputDirectory>
                            <silent>true</silent>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>javax</groupId>
                                    <artifactId>javaee-endorsed-api</artifactId>
                                    <version>6.0</version>
                                    <type>jar</type>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        <finalName>SitemeshExample</finalName>
    </build>
</project>

and this is my web.xml file,

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <display-name>Sitemesh</display-name>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    
    <filter>
        <filter-name>sitemesh</filter-name>
        <filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>
    </filter>
 
    <filter-mapping>
        <filter-name>sitemesh</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

next step is creating decorators.xml under WEB-INF folder

<?xml version="1.0" encoding="UTF-8"?>
<decorators>
    <excludes>
        <pattern>/index.jsp</pattern> <!-- exclude example -->
        <pattern>*.js</pattern> <!-- exclude css files -->
        <pattern>*.css</pattern> <!-- exclude js files -->
    </excludes>
    <decorator name="basic-theme" page="/template/theme.jsp">        
        <pattern>/*</pattern>        
    </decorator>
</decorators>

and a base html template

<?xml version="1.0" encoding="UTF-8" ?>
<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Title</title>
</head>
<body>
    <h1>Header</h1>
    <p><b>Menu</b></p>
    
    <decorator:body />
    
    <h1>Footer</b></h1>
</body>
</html>

And 2 .jsp files for example, index.jsp and dodol.jsp
index.jsp

<div>
    <h2>Hello WORLD...!! (Without Sitemesh)</h2>
</div>

and dodol.jsp

    <h1>Hello World! (With Sitemesh)</h1>

these is the screenshot when i deploy my application,

and this is my netbeans project structure