Archive for the ‘WebProgramming’ Category

Source: https://sites.google.com/site/joeztechland/how-to–in-adf

ADF BC (Model)

ADF Faces (UI)
Bindings:
– DataProvider code example: here

VOs: Single, Shared VO Instance or Multiple?

Page Behavior:
– Prevent initial page render: adfFacesInitialContext Render Issues: here and here

Passing Data as Parameters (how to get data from point A to point B)
1. Data Bindings
– Value is set in bindings tab via NDValue property: This value can be EL and reference backing bean methods (that return a value), scopes (pageFlowScope, requestScope)
— this makes the value available to the resource that it is bound to and whose param has the NDValue. T

2. Task Flows
– URL Params: Capture in Task Flow properties. Move to a scope: ex: pageFlowScope.varname (tf param is copied to destination)
– Method Calls:
Created w/ TF Method Call: Method name entered manaully into Method call or through D&D onto TF method Call.
Params set in Property Window for Method
Can use return value for Navigation or not
— Create method call in TF and then associate method with it and then its params
– Method call via D&D from Data Control onto TF:
Params set in PageDef

3. SetCurrentRowWithKey (or KeyValue)
– With Command Link:
Set row – in bindings row.RowKeyStr (rowkey=row.rowKeyStr)
And link sends action for navigation
Command link action listener calls rowkey.execute – passes current row and navigate to destination and executes query from rowkey.execute

4. Page Params
– Add Params to Pagedef. Give Params a source (value = ex: pageFlowScope.xxx)
– then , can use params w/ service methods
Method: param1 NVDValue = bindings.paramname (note: bindings not pageFlowScope)

5. SetAction Listener to store values: main way to copy values using from: and to:

Use setCurrentRowWithKey/Value (video)
– use setCurrent to auto fire findbykey() – on entry to new page – keeps the new page current withthe current row
– can fire action so can be used (typically IS used ) for navigation
– task flow with search and edit forms and flows
– table in edit – add setcurr call. set its text value to column EL value and delete that value
– in bindings, setcurrr rowKey NDValue to value from column (key col)
— If key value is a string and can be viewed as normal data, use …WithKeyValue
— If key is obtained by getKey() on a VO , then it is sthe serialized string version of key and use …WithKey

Use ExecuteWithParams

Expose ADFbc as Web Service

Expose Web Service as Data Control

Query Component:
– Read only fields in query comp: open ER#10431603
– Capture internal components events/reference: ER or not possible
– Auto suggest on internal fields: ER#9797027
– Popup content headers not sizing correctly: Fixed in 11.1.1.4
– How to tell view criteria used by query comp: here
– Save Queries across sessions: here

Train Component:
– Validating train flow: here

Exception Handling:
– multiple callbacks to DCErrorHandlerImpl http://forums.oracle.com/forums/thread.jspa?threadID=1805073
– how to show multiple messages for a single exception http://forums.oracle.com/forums/thread.jspa?threadID=1805074
– how to configure logging for Utils buildFacesMessage http://forums.oracle.com/forums/thread.jspa?threadID=1805075
– HTML tags returned from DCErrorMessage.getHTMLText() http://forums.oracle.com/forums/thread.jspa?threadID=1805076
– DCErrorHandlerImpl sub-class super(true) or super(false)at http://forums.oracle.com/forums/thread.jspa?threadID=1805078
– DCErrorHandlerImpl.processMessage() method http://forums.oracle.com/forums/thread.jspa?threadID=1807859

and more
– the phase when exceptions are translated to JSF FacesMessage objects http://forums.oracle.com/forums/thread.jspa?threadID=2134598
– an EL expression that evaluates the type of exception http://forums.oracle.com/forums/thread.jspa?threadID=2151981
– abstract method handleException() cannot be accessed directly http://forums.oracle.com/forums/thread.jspa?threadID=2151982
– how to designate custom code as an exception handler http://forums.oracle.com/forums/thread.jspa?threadID=2151983
– ExceptionHandler implementation and activity marked as “Exception
– Handler” http://forums.oracle.com/forums/thread.jspa?threadID=2151984

Tips and Tricks:
LOVs:
Returning non key value: query lov col, as “code” make attribute a key attribute. In LOV usage on VO, return code into the desired text field

ViewCriteria
Can have VC criteria = literal with no value if bind vars will not be used.

How ADF Faces can do Tiles or SiteMesh like Push-Style templating using Regions with Dynamic Attributes by Lucas Jellema

Source: AMIS’s Blog

JSF has in built in facility for templating, apart from the subview component. And the Subview does not give us the kind of push-style templating that has us define templates and apply them to page-specific content, such as demonstrated in this illustration:

Here we push page specific content and place holder values to a generic template that meshes the two together to produce a page that has both the generic, centrally maintained, template as well as the page specific stuff.

There are several ways of using Tiles and JSF together (see for example http://www.jsftutorials.net/tiles/jsf-tiles.html ).

In this article, I will focus on the Region component in ADF Faces. This component also allows us to do something very similar to the above example. But let’s first introduce Regions, as they are typically used. ....
A Region in ADF Faces is a parametrized reusable page fragment. A region is very much like a regular JSF page, that defines a piece of content that can easily be reused in many different pages. Additionally, the region can make use of dynamically defined parameters whose values are passed along with the region inclusion.

This Find Books page includes two Regions:

1. the Global Menu region is a static fragment that returns three global buttons that are to be displayed in every page in the application.

2. the AlsMainMenu region, an almost static fragment, that displays the application wide menu (it is a small application we are talking about) and highlights the currently selected menu-tab. This last piece is dynamic: every page that includes the AlsMainMenu will have to specify which tab in the menu should be highlighted.

In order to use regions like this, the FindBooks-page has these two region elements:

<af:region id="menuGlobal"
           regionType="nl.amis.als.region.globalMenu"/>
<af:region id="mainmenu"
           regionType="nl.amis.als.region.AlsMainMenu">
   <af:attribute name="selectedTab" value="findbooks"/>
</af:region> 

The second region element contains an af:attribute that allows us to pass a pagespecific value.

The two regions are defined in separate pages, that can be named anything and be located anywhere, as we use a metadata file where all regions are registered, with their page name and location. The AlsMainMenu region for example is defined as follows:

Note how the region AlsMainMenu can refer to the dynamic values passed into it from the <af:region> tag (attribute child element). The Find Books tab is only selected when the EL expression evaluates to true, which means only when the attrs.selectedTab value equals findbooks.

In order for the region reference in the FindBooks.jspx to be evaluated correctly by ADF Faces, we need to add the proper region registration to a file called region-metadata.xml located in the WEB-INF directory. The region meta-data for GlobalMenu and AlsMainMenu look like:

<?xml version="1.0" encoding="windows-1252"?>
<!DOCTYPE faces-config PUBLIC
  "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
  "http://java.sun.com/dtd/web-facesconfig_1_1.dtd"[
<!ELEMENT region-jsp-ui-def (#PCDATA)>
<!ELEMENT required (#PCDATA)>
]>
<faces-config xmlns="http://java.sun.com/JSF/Configuration">
  <component>
    <component-type>nl.amis.als.region.globalMenu</component-type>
    <component-class>oracle.adf.view.faces.component.UIXRegion</component-class>
    <component-extension>
      <region-jsp-ui-def>/regions/globalMenu.jspx</region-jsp-ui-def>
    </component-extension>
  </component>
  <component>
    <component-type>nl.amis.als.region.AlsMainMenu</component-type>
    <component-class>oracle.adf.view.faces.component.UIXRegion</component-class>
    <attribute>
      <attribute-name>selectedTab</attribute-name>
      <attribute-class>java.lang.String</attribute-class>
      <attribute-extension>
        <required>false</required>
      </attribute-extension>
    </attribute>
    <component-extension>
      <region-jsp-ui-def>/regions/AlsMainMenu.jspx</region-jsp-ui-def>
    </component-extension>
  </component>
</faces-config>

Now we have been introduced to basic way of working with regions. Let’s turn next to page wide templates.

ADF Faces page templates

ADF Faces does not really have the concept of Page Templates. A Page Template is a page definition that provides the generic elements that return on every page in the application. These elements by and large determine the look & feel of the application (along of course with the stylesheets). Look for example at two pages in our application, and it becomes soon clear what would be part of the template for this application:

The overall page template is consists of:

  • Fixed elements such as Logo, Application Title, Global menu and Application menu, Copyright Message, Side Menu Bar
  • Page specific content (the yellow area that differs per page)
  • Dynamic elements whose appearance and position is fixed but whose values/settings are page-specific, such a Page Title, Tip and Selected MenuTab

If we do nothing special, working with ADF Faces Regions does not really help us here. Since the page template is all over the page, we cannot include a single region to apply a default template. The page specific content somehow would have to be injected into a generic template that is also customized in certain elements with page specific values. Besides, each page still needs its own JSPX file to cater for proper navigation and support for ADF Faces Model and Page Definitions. So at the moment, the page template is copied for every new page that gets created. The generic template is applied initially for every page. But changes in the generic template can only be applied globally by revisiting and changing every individual page that was once created from the template file.

Inside-out  Template usage

What we would like to do is somehow turn the concept of the template inside-out. The page specifies the template to be applied, provides page specific values but does not copy the template but only references it. Then we can still make changes to the overall appearance of the application in a single location.

It took a little puzzling, but I managed to do this using Regions in ADF Faces. The set up is as follows:

Every page in the application has its own JSPX file with the page definition. This definition consists of nothing more than the inclusion of one or more regions, passing to each region a number of page specific details. These details include the values for a number of placeholders in the referenced template and a reference to a second region that contains the page specific content. This latter reference is used in the main template file to include another region – the yellow area in the picture below – with page specific content. The key to this approach is that the region reference in the main template is dynamic: each page provides its own value for this region reference.

The three pages in our application now have very simple page definitions – as all their content is either provided by the main template or their page specific region counterparts. The FindBookPage.jspx is defined like this:

<?xml version='1.0' encoding='windows-1252'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:af="http://xmlns.oracle.com/adf/faces" >
  <jsp:output omit-xml-declaration="true" doctype-root-element="HTML"
              doctype-system="http://www.w3.org/TR/html4/loose.dtd"
              doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"/>
  <jsp:directive.page contentType="text/html;charset=windows-1252"/>
  <f:view>
    <afh:html>
      <afh:head title="AMIS Library  System - Find Book">
        <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"/>
      </afh:head>
      <afh:body>
        <af:form>
          <af:region id="mainTemplate" regionType="nl.amis.als.region.mainTemplate">
            <af:attribute name="contentRegion" value="nl.amis.als.region.FindBookPage"/>
            <af:attribute name="title" value="Find Books"/>
            <af:attribute name="selectedMenuTab" value="findbooks"/>
            <af:attribute name="pageTip" value="Specify the search criteria for finding selected books."/>
          </af:region>
        </af:form>
      </afh:body>
    </afh:html>
  </f:view>
</jsp:root>

That is, the page is nothing more than a parametrized usage of the MainTemplate region.

The MainTemplate is registered in the region-metadata.xml file as follows:

  <component>
    <component-type>nl.amis.als.region.mainTemplate</component-type>
    <component-class>oracle.adf.view.faces.component.UIXRegion</component-class>
    <attribute>
      <attribute-name>selectedTab</attribute-name>
      <attribute-class>java.lang.String</attribute-class>
      <attribute-extension>
        <required>false</required>
      </attribute-extension>
    </attribute>
    <attribute>
      <attribute-name>contentRegion</attribute-name>
      <attribute-class>java.lang.String</attribute-class>
      <attribute-extension>
        <required>false</required>
      </attribute-extension>
    </attribute>
    <attribute>
      <attribute-name>title</attribute-name>
      <attribute-class>java.lang.String</attribute-class>
      <attribute-extension>
        <required>false</required>
      </attribute-extension>
    </attribute>
    <attribute>
      <attribute-name>pageTip</attribute-name>
      <attribute-class>java.lang.String</attribute-class>
      <attribute-extension>
        <required>false</required>
      </attribute-extension>
    </attribute>
    <component-extension>
      <region-jsp-ui-def>/regions/MainTemplate.jspx</region-jsp-ui-def>
    </component-extension>
  </component>

It has four attributes, for the dynamic values to be passed into the template, to populate the three place holders – selected menu tab, title and tip – and to refer to the content region.

Here are a few fragments from the MainTemplate.jspx file.

<?xml version='1.0' encoding='windows-1252'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:af="http://xmlns.oracle.com/adf/faces"
          xmlns:afh="http://xmlns.oracle.com/adf/faces/html">
  <jsp:output omit-xml-declaration="true" doctype-root-element="HTML"
              doctype-system="http://www.w3.org/TR/html4/loose.dtd"
              doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"/>
  <jsp:directive.page contentType="text/html;charset=windows-1252"/>
  <af:regionDef var="attrs">
     <af:panelPage title="#{attrs.title}">
       <f:facet name="menu1"/>
       <f:facet name="menuGlobal">
         <af:region id="menuGlobal"
                    regionType="nl.amis.als.region.globalMenu"/>
       </f:facet>
       <f:facet name="infoFootnote">
         <af:panelTip>
           <af:outputFormatted value="#{attrs.pageTip}"></af:outputFormatted>
         </af:panelTip>
       </f:facet>
       <f:facet name="menu1">
         <af:region id="mainmenu"
                    regionType="nl.amis.als.region.AlsMainMenu">
           <af:attribute name="selectedTab" value="#{attrs.selectedMenuTab}"/>
         </af:region>
       </f:facet>
       …
       <af:region id="content" regionType="#{attrs.contentRegion}" />
     </af:panelPage>
   </af:regionDef>
</jsp:root>

This pages defines the main layout of the pages in our application, using an ADF Faces PanelPage component, setting up for example the Application Branding (logo and application title), the Copyright message, the global menu (by including the globalmenu region) and the application specific menu (through yet another region). The really novel part is the region with id=”content”. That is where we import the page content. And the region to load is specified by the page that includes the MainTemplate region.

The region-metadata.xml file contains region definitions for all pages in our application:

  <!-- regions with the real page content -->
  <component>
    <component-type>nl.amis.als.region.AlsHomePage</component-type>
    <component-class>oracle.adf.view.faces.component.UIXRegion</component-class>
    <component-extension>
      <region-jsp-ui-def>/regions/AlsHomeRegion.jspx</region-jsp-ui-def>
    </component-extension>
  </component>
  <component>
    <component-type>nl.amis.als.region.FindBookPage</component-type>
    <component-class>oracle.adf.view.faces.component.UIXRegion</component-class>
    <component-extension>
      <region-jsp-ui-def>/regions/FindBookRegion.jspx</region-jsp-ui-def>
    </component-extension>
  </component>
  <component>
    <component-type>nl.amis.als.region.BooksTablePrettyPage</component-type>
    <component-class>oracle.adf.view.faces.component.UIXRegion</component-class>
    <component-extension>
      <region-jsp-ui-def>/regions/BooksTablePrettyRegion.jspx</region-jsp-ui-def>
    </component-extension>
  </component>

These regions contain the real content for all pages.

Our web application now is structured like this:

where three pages each have their own jspx file, referenced in the faces-config.xml file for navigation purposes, but otherwise consisting of nothing more than a reference to the MainTemplate region that is specified in region-metadata.xml and refers to the regions\MainTemplate.jspx file. This file in turn includes the regions GobalMenu and AlsMainMenu, and is parameterized with four page specific values. The MainTemplate.jsxp page has a dynamic region reference; the page that includes the MainTemplate tells the MainTemplate which region to refer in this dynamic reference. The region reference thus passed is resolved via the region-metadata.xml and results in including the page specific region – AlsHomeRegion.jspx, FindBookRegion.jspx or BooksTablePrettyRegion.jspx.

If we want to change the overall appearance and structure of the pages in our application, we change the MainTemplate.jspx file and nothing but this MainTemplate. We do not need to visit each and every page individually.

Unfortunately, it does not quite work like this

It turns out that the evaluation of the regionType attribute in the af:region element is performed too late. If we pass in a value, evaluation of #{attrs.contentRegion} is done at the wrong moment and we get fairly nasty error:

So we have to resort to a workaround, that allows us to specify the name of the region to be included by the MainTemplate in the page while keeping it dynamic. It turns out that we can refer to a managed bean in the regionType attribute without having this too-late-evaluation issue that we have with the attrs ‘value container’.

What proves to work for me, though it may sound a little complex at first, is the following:

<af:region id="content" regionType="#{Helper.contentRegion}">

in the MainTemplate.jspx. The regionType is set to an EL Expression that does not refer to attrs but instead to a managed bean, lamely called Helper.

In the pages, we have to do the following to pass the value of the region to be injected in the MainTemplate:

<af:region id="mainTemplate" regionType="#{DynamicPageRegionHolder['nl.amis.als.region.FindBookPage']}">
   <af:attribute name="title" value="Find Books"/>
   <af:attribute name="selectedMenuTab" value="findbooks"/>
   <af:attribute name="pageTip" value="Specify the search criteria for finding selected books."/>
</af:region>

This is uses another trick: in order to pass the value of the region we want to include at the right time we use an EL Expression for the mainTemplate region’s regionType attribute. The managed bean referenced here – DynamicPageRegionHolder – implements the Map interface. The EL expression #{DynamicPageRegionHolder[’nl.amis.als.region.FindBookPage’]}  will have the get(Object key) method in this bean invoked. The value of the key parameter will be the region identification for the region to be injected by the MainTemplate region. The get() method currently always returns the region identification for the MainTemplate and stores the page specific contentRegion identification in the Helper bean that is subsequently consulted by the MainTemplate region.

The get() method in the DynamicPageRegionHolder bean:

    public Object get(Object key) {
      helper.setContentRegion((String)key);
      return "nl.amis.als.region.mainTemplate";
    }

The configuration of the two beans in the faces-config.xml file:

  <managed-bean>
    <managed-bean-name>Helper</managed-bean-name>
    <managed-bean-class>nl.amis.Helper</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
  </managed-bean>
  <managed-bean>
    <managed-bean-name>DynamicPageRegionHolder</managed-bean-name>
    <managed-bean-class>nl.amis.MapAdaptor</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    <managed-property>
      <property-name>helper</property-name>
      <property-class>nl.amis.Helper</property-class>
      <value>#{Helper}</value>
    </managed-property>
  </managed-bean>

It is a somewhat nasty trick. But it does the job.

Resources

Download the JDeveloper 10.1.3.2 project with sources for this article.  NestedRegions_ADFFaces.zip (note: you have to add the adf-faces-impl.jar and the faces-impl.jar libraries to the WEB-INF\lib directory (saves 4 Mb on download).

When developing JSF pages using Oracle ADF Faces 10.1.3.3, I encountered the error that is reported at the top of the page as: JBO-35007 indicated that the row currency has changed since last visit or something. This was so annoy that it is repeatedly occurred everytimes I hit the back button. Sometimes it disappear when I press Refresh.
Googling around, I found two working solutions for the error:

1.Go to page definition of jsp or jspx by right click on page.
2.Select Iterator of page by using structure window or definition page
3.Go to the Inspector window and change the StateValidation property as false.

“And as can be seen from the JDev doco note, the row currency token mechanism can be turned off per page through the pageDef for your page, setting the EnableTokenValidation to false. (Be warned you should not flippantly turn this off for pages, or blanket turn it off for all pages, as the mechanism is an important one)

So enjoy your programming…

Minh-Tran

Source: OTN JDeveloper Forum

All

Just successfully deployed a JSF/ADF-BC4J app developed in Jdev 10.1.3.3 to Tomcat-6.0.14 and MySQL 5.0

Thought I would share since i could not find anything out there that gave me the steps for this configuration combo.

Assumptions:
1. install MySQL 5.0 database with some tables.
2. install Tomcat-6.0.14 (http://archive.apache.org/dist/tomcat/tomcat-6/v6.0.14/bin/) probably any 6.x build would be same
3. Application Modules developed in Jdev are currently configured to run on MySQL (SQL92 flavor / Java type mappings)
4. This is for ADF-BC4J only. TopLink would require add’l steps, though I assume the only difference would be add’l jar files

I did all development in Jdev using the internal OC4J and a local MySQL before deploying to Tomcat.

Steps:
1. copy following jars from <JDEV_INSTALL> to <TOMCAT_HOME>\lib\
(Note that ‘Tools -> ADF Runtime Installer’ does not work for Tomcat 6.x, so this has to be manual)

\BC4J\lib\adfcm.jar
\BC4J\lib\adfm.jar
\BC4J\lib\adfmweb.jar
\BC4J\lib\adfshare.jar
\BC4J\lib\bc4jct.jar
\BC4J\lib\bc4jctejb.jar
\BC4J\lib\bc4jdomorcl.jar
\BC4J\lib\bc4jimdomains.jar
\BC4J\lib\bc4jmt.jar
\BC4J\lib\bc4jmtejb.jar
\BC4J\lib\collections.jar
\BC4J\jlib\bc4jdomgnrc.jar
\BC4J\jlib\adfmtl.jar
\BC4J\jlib\adfui.jar
\jlib\commons-cli-1.0.jar
\jlib\xmlef.jar
\jlib\share.jar
\mds\lib\mdsrt.jar
\mds\lib\concurrent.jar
\diagnostics\lib\ojdl.jar
\jlib\jdev-cm.jar
\jlib\commons-el.jar
\jlib\oracle-el.jar
\jlib\jsp-el-api.jar
\toplink\jlib\toplink.jar
\toplink\jlib\antlr.jar
\BC4J\lib\adfbinding.jar
\lib\xmlparserv2.jar
\lib\xml.jar
\lib\xsqlserializers.jar
\lib\xsu12.jar
\ord\jlib\ordhttp.jar
\ord\jlib\ordim.jar
\sqlj\lib\runtime12.jar
\sqlj\lib\translator.jar
\jdbc\lib\ojdbc14.jar
\jdbc\lib\ojdbc14dms.jar
\lib\dms.jar
\javacache\lib\cache.jar
\BC4J\jlib\dc-adapters.jar
\BC4J\jlib\adf-connections.jar
\webservices\lib\wsdl.jar
\webservices\lib\orajaxr.jar
\webservices\lib\orawsrm.jar
\webservices\lib\wsclient.jar
\webservices\lib\orasaaj.jar
\webservices\lib\xsdlib.jar
\webservices\lib\mdds.jar
\webservices\lib\wssecurity.jar
\webservices\lib\orawsdl.jar
\jlib\osdt_core.jar
\jlib\osdt_cert.jar
\jlib\osdt_xmlsec.jar
\jlib\osdt_wss.jar
\jlib\osdt_saml.jar
\jlib\ojpse.jar
\jlib\oraclepki.jar
\j2ee\home\jazncore.jar
\j2ee\home\lib\http_client.jar

2. copy <JDEV_INSTALL>\BC4J\redist\webapp.war to <TOMCAT_HOME>\webapps\webapp.war

3. in your application’s webroot, create a META-INF folder containing a single file, named ‘context.xml’, with the following (enter your appropriate values as usual):

<?xml version=”1.0″ encoding=”UTF-8″?>
<Context
antiJARLocking=”true”
antiResourceLocking=”true”
reloadable=”true”>
<Resource
auth=”Container”
name=”jdbc/MySqlDS”
type=”com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource”
factory=”com.mysql.jdbc.jdbc2.optional.MysqlDataSourceFactory”
driverClassName=”com.mysql.jdbc.Driver”
maxIdle=”2″
maxWait=”5000″
url=”jdbc:mysql://<HOSTNAME>:<PORT>/<DATABASE>?&ultraDevHack=true&capitalizeTypeNames=true&pedantic=true”
user=”<USERNAME>”
password=”<PASSWORD>”
databaseName=”<DATABASE>”
port=”<PORT>”
maxActive=”10″/>
<Manager
className=”org.apache.catalina.session.PersistentManager”
saveOnRestart=”false”/>
</Context>

4. in all Application Modules, set the Configuration to use a ‘JDBC Datasource’ with the name set to the named datasource in the context.xml created above, e.g.: ‘java:comp/env/jdbc/MySqlDS’

5. create a deployment profile with ‘Platform -> target connection’ set to the Tomcat instance (need to create an entry in ‘Connections -> Application Server’ for it to show up) make sure to include the correct mysql-connector.jar in the ‘WEB-INF/lib’ contributors.
Right-click -> Deploy to your tomcat

6. Make sure MySQL is on and fire up Tomcat, and youre set.

Hope it helps
Sami


HWPFF là một thành phần của bộ thư viện Apache POI cho phép bạn tương tác với Microsoft Exel sử dụng ngôn ngữ Java. Các tính năng chủ yếu của Apache POI bao gồm:

Tạo mới một workbook

HSSFWorkbook wb = new HSSFWorkbook();
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();

Tạo mới một sheet

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet1 = wb.createSheet("new sheet");
HSSFSheet sheet2 = wb.createSheet("second sheet");
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();

Tạo cell

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");
// Create a row and put some cells in it. Rows are 0 based.
HSSFRow row = sheet.createRow((short)0);
// Create a cell and put a value in it.
HSSFCell cell = row.createCell((short)0);
cell.setCellValue(1);

// Or do it on one line.
row.createCell((short)1).setCellValue(1.2);
row.createCell((short)2).setCellValue("This is a string");
row.createCell((short)3).setCellValue(true);

// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();

Tạo cell với giá trị là ngày tháng

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");

// Create a row and put some cells in it. Rows are 0 based.
HSSFRow row = sheet.createRow((short)0);

// Create a cell and put a date value in it. The first cell is not styled
// as a date.
HSSFCell cell = row.createCell((short)0);
cell.setCellValue(new Date());

// we style the second cell as a date (and time). It is important to
// create a new cell style from the workbook otherwise you can end up
// modifying the built in style and effecting not only this cell but other cells.
HSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"));
cell = row.createCell((short)1);
cell.setCellValue(new Date());
cell.setCellStyle(cellStyle);

// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();

Làm việc với nhiều loại cell

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");
HSSFRow row = sheet.createRow((short)2);
row.createCell((short) 0).setCellValue(1.1);
row.createCell((short) 1).setCellValue(new Date());
row.createCell((short) 2).setCellValue("a string");
row.createCell((short) 3).setCellValue(true);
row.createCell((short) 4).setCellType(HSSFCell.CELL_TYPE_ERROR);

// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();


Điều chỉnh cell

public static void main(String[] args)
throws IOException
{
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");
HSSFRow row = sheet.createRow((short) 2);
createCell(wb, row, (short) 0, HSSFCellStyle.ALIGN_CENTER);
createCell(wb, row, (short) 1, HSSFCellStyle.ALIGN_CENTER_SELECTION);
createCell(wb, row, (short) 2, HSSFCellStyle.ALIGN_FILL);
createCell(wb, row, (short) 3, HSSFCellStyle.ALIGN_GENERAL);
createCell(wb, row, (short) 4, HSSFCellStyle.ALIGN_JUSTIFY);
createCell(wb, row, (short) 5, HSSFCellStyle.ALIGN_LEFT);
createCell(wb, row, (short) 6, HSSFCellStyle.ALIGN_RIGHT);

// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();

}

/**
* Creates a cell and aligns it a certain way.
*
* @param wb the workbook
* @param row the row to create the cell in
* @param column the column number to create the cell in
* @param align the alignment for the cell.
*/
private static void createCell(HSSFWorkbook wb, HSSFRow row, short column, short align)
{
HSSFCell cell = row.createCell(column);
cell.setCellValue("Align It");
HSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setAlignment(align);

cell.setCellStyle(cellStyle);
}


Làm việc với border

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");

// Create a row and put some cells in it. Rows are 0 based.
HSSFRow row = sheet.createRow((short) 1);

// Create a cell and put a value in it.
HSSFCell cell = row.createCell((short) 1);
cell.setCellValue(4);

// Style the cell with borders all around.
HSSFCellStyle style = wb.createCellStyle();
style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
style.setBottomBorderColor(HSSFColor.BLACK.index);
style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
style.setLeftBorderColor(HSSFColor.GREEN.index);
style.setBorderRight(HSSFCellStyle.BORDER_THIN);
style.setRightBorderColor(HSSFColor.BLUE.index);
style.setBorderTop(HSSFCellStyle.BORDER_MEDIUM_DASHED);
style.setTopBorderColor(HSSFColor.BLACK.index);
cell.setCellStyle(style);

// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();


Tô màu và màu sắc

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");

// Create a row and put some cells in it. Rows are 0 based.
HSSFRow row = sheet.createRow((short) 1);

// Aqua background
HSSFCellStyle style = wb.createCellStyle();
style.setFillBackgroundColor(HSSFColor.AQUA.index);
style.setFillPattern(HSSFCellStyle.BIG_SPOTS);
HSSFCell cell = row.createCell((short) 1);
cell.setCellValue("X");
cell.setCellStyle(style);

// Orange "foreground", foreground being the fill foreground not the font color.
style = wb.createCellStyle();
style.setFillForegroundColor(HSSFColor.ORANGE.index);
style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
cell = row.createCell((short) 2);
cell.setCellValue("X");
cell.setCellStyle(style);

// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();


Trộn dòng, cột

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");

HSSFRow row = sheet.createRow((short) 1);
HSSFCell cell = row.createCell((short) 1);
cell.setCellValue("This is a test of merging");

sheet.addMergedRegion(new Region(1,(short)1,1,(short)2));

// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();

Làm việc với font

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");

// Create a row and put some cells in it. Rows are 0 based.
HSSFRow row = sheet.createRow((short) 1);

// Create a new font and alter it.
HSSFFont font = wb.createFont();
font.setFontHeightInPoints((short)24);
font.setFontName("Courier New");
font.setItalic(true);
font.setStrikeout(true);

// Fonts are set into a style so create a new one to use.
HSSFCellStyle style = wb.createCellStyle();
style.setFont(font);

// Create a cell and put a value in it.
HSSFCell cell = row.createCell((short) 1);
cell.setCellValue("This is a test of fonts");
cell.setCellStyle(style);

// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();

Tùy chỉnh màu sắc

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
HSSFRow row = sheet.createRow((short) 0);
HSSFCell cell = row.createCell((short) 0);
cell.setCellValue("Default Palette");

//apply some colors from the standard palette,
// as in the previous examples.
//we'll use red text on a lime background

HSSFCellStyle style = wb.createCellStyle();
style.setFillForegroundColor(HSSFColor.LIME.index);
style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);

HSSFFont font = wb.createFont();
font.setColor(HSSFColor.RED.index);
style.setFont(font);

cell.setCellStyle(style);

//save with the default palette
FileOutputStream out = new FileOutputStream("default_palette.xls");
wb.write(out);
out.close();

//now, let's replace RED and LIME in the palette
// with a more attractive combination
// (lovingly borrowed from freebsd.org)

cell.setCellValue("Modified Palette");

//creating a custom palette for the workbook
HSSFPalette palette = wb.getCustomPalette();

//replacing the standard red with freebsd.org red
palette.setColorAtIndex(HSSFColor.RED.index,
(byte) 153, //RGB red (0-255)
(byte) 0, //RGB green
(byte) 0 //RGB blue
);
//replacing lime with freebsd.org gold
palette.setColorAtIndex(HSSFColor.LIME.index, (byte) 255, (byte) 204, (byte) 102);

//save with the modified palette
// note that wherever we have previously used RED or LIME, the
// new colors magically appear
out = new FileOutputStream("modified_palette.xls");
wb.write(out);
out.close();

Đọc và ghi

POIFSFileSystem fs =
new POIFSFileSystem(new FileInputStream("workbook.xls"));
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFSheet sheet = wb.getSheetAt(0);
HSSFRow row = sheet.getRow(2);
HSSFCell cell = row.getCell((short)3);
if (cell == null)
cell = row.createCell((short)3);
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
cell.setCellValue("a test");

// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();


Làm việc với nhiều dòng trong cell.

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet s = wb.createSheet();
HSSFRow r = null;
HSSFCell c = null;
HSSFCellStyle cs = wb.createCellStyle();
HSSFFont f = wb.createFont();
HSSFFont f2 = wb.createFont();

cs = wb.createCellStyle();

cs.setFont( f2 );
//Word Wrap MUST be turned on
cs.setWrapText( true );

r = s.createRow( (short) 2 );
r.setHeight( (short) 0x349 );
c = r.createCell( (short) 2 );
c.setCellType( HSSFCell.CELL_TYPE_STRING );
c.setCellValue( "Use \n with word wrap on to create a new line" );
c.setCellStyle( cs );
s.setColumnWidth( (short) 2, (short) ( ( 50 * 8 ) / ( (double) 1 / 20 ) ) );

FileOutputStream fileOut = new FileOutputStream( "workbook.xls" );
wb.write( fileOut );
fileOut.close();

Định dạng dữ liệu

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("format sheet");
HSSFCellStyle style;
HSSFDataFormat format = wb.createDataFormat();
HSSFRow row;
HSSFCell cell;
short rowNum = 0;
short colNum = 0;

row = sheet.createRow(rowNum++);
cell = row.createCell(colNum);
cell.setCellValue(11111.25);
style = wb.createCellStyle();
style.setDataFormat(format.getFormat("0.0"));
cell.setCellStyle(style);

row = sheet.createRow(rowNum++);
cell = row.createCell(colNum);
cell.setCellValue(11111.25);
style = wb.createCellStyle();
style.setDataFormat(format.getFormat("#,##0.0000"));
cell.setCellStyle(style);

FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();


Chỉnh kích thước Sheet

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("format sheet");
HSSFPrintSetup ps = sheet.getPrintSetup();

sheet.setAutobreaks(true);

ps.setFitHeight((short)1);
ps.setFitWidth((short)1);

// Create various cells and rows for spreadsheet.

FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();

Print

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("Sheet1");
wb.setPrintArea(0, "$A$1:$C$2");
//sets the print area for the first sheet
//Alternatively:
//wb.setPrintArea(0, 0, 1, 0, 0) is equivalent to using the name reference (See the JavaDocs for more details)

// Create various cells and rows for spreadsheet.

FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();


Đánh số trang cho footer trong sheet

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("format sheet");
HSSFFooter footer = sheet.getFooter();

footer.setRight( "Page " + HSSFFooter.page() + " of " + HSSFFooter.numPages() );

// Create various cells and rows for spreadsheet.

FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();

Convenience Functions

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet1 = wb.createSheet( "new sheet" );

// Create a merged region
HSSFRow row = sheet1.createRow( (short) 1 );
HSSFRow row2 = sheet1.createRow( (short) 2 );
HSSFCell cell = row.createCell( (short) 1 );
cell.setCellValue( "This is a test of merging" );
Region region = new Region( 1, (short) 1, 4, (short) 4 );
sheet1.addMergedRegion( region );

// Set the border and border colors.
final short borderMediumDashed = HSSFCellStyle.BORDER_MEDIUM_DASHED;
HSSFRegionUtil.setBorderBottom( borderMediumDashed,
region, sheet1, wb );
HSSFRegionUtil.setBorderTop( borderMediumDashed,
region, sheet1, wb );
HSSFRegionUtil.setBorderLeft( borderMediumDashed,
region, sheet1, wb );
HSSFRegionUtil.setBorderRight( borderMediumDashed,
region, sheet1, wb );
HSSFRegionUtil.setBottomBorderColor(HSSFColor.AQUA.index, region, sheet1, wb);
HSSFRegionUtil.setTopBorderColor(HSSFColor.AQUA.index, region, sheet1, wb);
HSSFRegionUtil.setLeftBorderColor(HSSFColor.AQUA.index, region, sheet1, wb);
HSSFRegionUtil.setRightBorderColor(HSSFColor.AQUA.index, region, sheet1, wb);

// Shows some usages of HSSFCellUtil
HSSFCellStyle style = wb.createCellStyle();
style.setIndention((short)4);
HSSFCellUtil.createCell(row, 8, "This is the value of the cell", style);
HSSFCell cell2 = HSSFCellUtil.createCell( row2, 8, "This is the value of the cell");
HSSFCellUtil.setAlignment(cell2, wb, HSSFCellStyle.ALIGN_CENTER);

// Write out the workbook
FileOutputStream fileOut = new FileOutputStream( "workbook.xls" );
wb.write( fileOut );
fileOut.close();

Hoán đổi dòng

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("row sheet");

// Create various cells and rows for spreadsheet.

// Shift rows 6 - 11 on the spreadsheet to the top (rows 0 - 5)
sheet.shiftRows(5, 10, -5);

FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();


Chọn sheet

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("row sheet");
sheet.setSelected(true);

// Create various cells and rows for spreadsheet.

FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();

Chọn hiển thị cho sheet

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet1 = wb.createSheet("new sheet");
sheet1.setZoom(3,4); // 75 percent magnification
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();


Chia dòng, cell

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet1 = wb.createSheet("new sheet");
HSSFSheet sheet2 = wb.createSheet("second sheet");
HSSFSheet sheet3 = wb.createSheet("third sheet");
HSSFSheet sheet4 = wb.createSheet("fourth sheet");

// Freeze just one row
sheet1.createFreezePane( 0, 1, 0, 1 );
// Freeze just one column
sheet2.createFreezePane( 1, 0, 1, 0 );
// Freeze the columns and rows (forget about scrolling position of the lower right quadrant).
sheet3.createFreezePane( 2, 2 );
// Create a split with the lower left side being the active quadrant
sheet4.createSplitPane( 2000, 2000, 0, 0, HSSFSheet.PANE_LOWER_LEFT );

FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();


Repeating rows and columns

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet1 = wb.createSheet("new sheet");
HSSFSheet sheet2 = wb.createSheet("second sheet");

// Set the columns to repeat from column 0 to 2 on the first sheet
wb.setRepeatingRowsAndColumns(0,0,2,-1,-1);

// Set the the repeating rows and columns on the second sheet.
wb.setRepeatingRowsAndColumns(1,4,5,1,2);

FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();


Headers and Footers

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");

HSSFHeader header = sheet.getHeader();
header.setCenter("Center Header");
header.setLeft("Left Header");
header.setRight(HSSFHeader.font("Stencil-Normal", "Italic") +
HSSFHeader.fontSize((short) 16) + "Right w/ Stencil-Normal Italic font and size 16");

FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();


Drawing Shapes

HSSFFont font = wb.createFont();
font.setItalic(true);
font.setUnderline(HSSFFont.U_DOUBLE);
HSSFRichTextString string = new HSSFRichTextString("Woo!!!");
string.applyFont(2,5,font);
textbox.setString(string );

// Create a shape group.
HSSFShapeGroup group = patriarch.createGroup(
new HSSFClientAnchor(0,0,900,200,(short)2,2,(short)2,2));

// Create a couple of lines in the group.
HSSFSimpleShape shape1 = group.createShape(new HSSFChildAnchor(3,3,500,500));
shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
( (HSSFChildAnchor) shape1.getAnchor() ).setAnchor((short)3,3,500,500);
HSSFSimpleShape shape2 = group.createShape(new HSSFChildAnchor((short)1,200,400,600));
shape2.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);

myGroup.setCoordinates(10,10,20,20); // top-left, bottom-right

Styling Shapes

HSSFSimpleShape s = patriarch.createSimpleShape(a);
s.setShapeType(HSSFSimpleShape.OBJECT_TYPE_OVAL);
s.setLineStyleColor(10,10,10);
s.setFillColor(90,10,200);
s.setLineWidth(HSSFShape.LINEWIDTH_ONE_PT * 3);
s.setLineStyle(HSSFShape.LINESTYLE_DOTSYS);


Shapes and Graphics2d

a = new HSSFClientAnchor( 0, 0, 1023, 255, (short) 1, 0, (short) 1, 0 );
group = patriarch.createGroup( a );
group.setCoordinates( 0, 0, 80 * 4 , 12 * 23 );
float verticalPointsPerPixel = a.getAnchorHeightInPoints(sheet) / (float)Math.abs(group.getY2() - group.getY1());
g = new EscherGraphics( group, wb, Color.black, verticalPointsPerPixel );
g2d = new EscherGraphics2d( g );
drawChemicalStructure( g2d );


Outlining

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet1 = wb.createSheet("new sheet");

sheet1.groupRow( 5, 14 );
sheet1.groupRow( 7, 14 );
sheet1.groupRow( 16, 19 );

sheet1.groupColumn( (short)4, (short)7 );
sheet1.groupColumn( (short)9, (short)12 );
sheet1.groupColumn( (short)10, (short)11 );

FileOutputStream fileOut = new FileOutputStream(filename);
wb.write(fileOut);
fileOut.close();

Hình ảnh

// Create the drawing patriarch. This is the top level container for
// all shapes. This will clear out any existing shapes for that sheet.
HSSFPatriarch patriarch = sheet5.createDrawingPatriarch();

HSSFClientAnchor anchor;
anchor = new HSSFClientAnchor(0,0,0,255,(short)2,2,(short)4,7);
anchor.setAnchorType( 2 );
patriarch.createPicture(anchor, loadPicture( "src/resources/logos/logoKarmokar4.png", wb ));

HSSFWorkbook wb;

List lst = wb.getAllPictures();
for (Iterator it = lst.iterator(); it.hasNext(); ) {
HSSFPictureData pict = (HSSFPictureData)it.next();
String ext = pict.suggestFileExtension();
byte[] data = pict.getData();
if (ext.equals("jpeg")){
FileOutputStream out = new FileOutputStream("pict.jpg");
out.write(data);
out.close();
}
}

Định danh một cụm và định danh một Cell

// setup code
String sname = "TestSheet", cname = "TestName", cvalue = "TestVal";
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet(sname);
sheet.createRow(0).createCell((short) 0).setCellValue(cvalue);

// 1. create named range for a single cell using areareference
HSSFName namedCell = wb.createName();
namedCell.setNameName(cname);
String reference = sname+"!A1:A1"; // area reference
namedCell.setReference(reference);

// 2. create named range for a single cell using cellreference
HSSFName namedCell = wb.createName();
namedCell.setNameName(cname);
String reference = sname+"!A1"; // cell reference
namedCell.setReference(reference);

// 3. create named range for an area using AreaReference
HSSFName namedCell = wb.createName();
namedCell.setNameName(cname);
String reference = sname+"!A1:C5"; // area reference
namedCell.setReference(reference);

// setup code
String cname = "TestName";
HSSFWorkbook wb = getMyWorkbook(); // retrieve workbook

// retrieve the named range
int namedCellIdx = wb.getNameIndex(cellName);
HSSFName aNamedCell = wb.getNameAt(namedCellIdx);

// retrieve the cell at the named range and test its contents
AreaReference aref = new AreaReference(aNamedCell.getReference());

CellReference[] crefs = aref.getCells();
for (int i=0; i
HSSFSheet s = wb.getSheet(crefs[i].getSheetName());
HSSFRow r = sheet.getRow(crefs[i].getRow());
HSSFCell c = r.getCell(crefs[i].getCol());
// extract the cell contents based on cell type etc.
}

Thiết lập comment cho cell

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("Cell comments in POI HSSF");

// Create the drawing patriarch. This is the top level container for all shapes including cell comments.
HSSFPatriarch patr = sheet.createDrawingPatriarch();

//create a cell in row 3
HSSFCell cell1 = sheet.createRow(3).createCell((short)1);
cell1.setCellValue(new HSSFRichTextString("Hello, World"));

//anchor defines size and position of the comment in worksheet
HSSFComment comment1 = patr.createComment(new HSSFClientAnchor(0, 0, 0, 0, (short)4, 2, (short) 6, 5));

// set text in the comment
comment1.setString(new HSSFRichTextString("We can set comments in POI"));

//set comment author.
//you can see it in the status bar when moving mouse over the commented cell
comment1.setAuthor("Apache Software Foundation");

// The first way to assign comment to a cell is via HSSFCell.setCellComment method
cell1.setCellComment(comment1);

//create another cell in row 6
HSSFCell cell2 = sheet.createRow(6).createCell((short)1);
cell2.setCellValue(36.6);

HSSFComment comment2 = patr.createComment(new HSSFClientAnchor(0, 0, 0, 0, (short)4, 8, (short) 6, 11));
//modify background color of the comment
comment2.setFillColor(204, 236, 255);

HSSFRichTextString string = new HSSFRichTextString("Normal body temperature");

//apply custom font to the text in the comment
HSSFFont font = wb.createFont();
font.setFontName("Arial");
font.setFontHeightInPoints((short)10);
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
font.setColor(HSSFColor.RED.index);
string.applyFont(font);

comment2.setString(string);
//by default comments are hidden. This one is always visible.
comment2.setVisible(true);

comment2.setAuthor("Bill Gates");

/**
* The second way to assign comment to a cell is to implicitly specify its row and column.
* Note, it is possible to set row and column of a non-existing cell.
* It works, the commnet is visible.
*/
comment2.setRow(6);
comment2.setColumn((short)1);

FileOutputStream out = new FileOutputStream("poi_comment.xls");
wb.write(out);
out.close();

HSSFCell cell = sheet.get(3).getColumn((short)1); HSSFComment comment = cell.getCellComment(); if (comment != null) { HSSFRichTextString str = comment.getString(); String author = comment.getAuthor(); } // alternatively you can retrieve cell comments by (row, column) comment = sheet.getCellComment(3, 1);

Chỉnh kích thước column vừa với nội dung

HSSFSheet sheet = workbook.getSheetAt(0);
sheet.autoSizeColumn((short)0); //adjust width of the first column
sheet.autoSizeColumn((short)1); //adjust width of the second column