Pages

Tuesday, 28 December 2010

VirtualBox: Managing Virtual Machines

Virtual Box is a virtualization software that allows many operating systems (guests) to run simultaneously on a host operating system. In the concept of cloud computing, it is increasingly common for server operating systems to be run in a virtual machine. The guest operating systems can be run in either headed or headless modes. The difference is that in "Headed" mode, the guest displays an interface similar to that displayed when the monitor is connected to the system.

It is ideal of run the guest operating systems that run as servers in headless mode.
The script below does just that. It is a bit buggy but works just fine. It was developed on Ubuntu but I expect it to run suitably on other Debian systems. It can be customized to run on other Linux/ UNIX distros.


   1 #!/bin/sh
   2 #Author: Emmanuel Toko
   3 #/etc/init.d/vbox_mgmt
   4 #
   5 ### BEGIN INIT INFO
   6 # Provides:          vm_mgmt
   7 # Required-Start:    $network $remote_fs $VBoxManage $VBoxHeadless $syslog
   8 # Required-Stop:     $network $remote_fs $VBoxManage $VBoxHeadless $syslog
   9 # Default-Start:     2 3 4 5
  10 # Default-Stop:      0 1 6
  11 # Short-Description: Start VMs in headless mode.
  12 # Description:       Run VMs for the default VirtualBox user in
  13 #                    headless mode. Make sure all VMs are using different RDP
  14 #                    ports.
  15 ### END INIT INFO
  16 
  17 VBOX_USER=chapati
  18 
  19 # The list of VMs to run. Leave empty to run all registered VMs.
  20 VBOX_LIST=""
  21 
  22 # VirtualBox executables
  23 VBOX_MANAGE=/usr/bin/VBoxManage
  24 VBOX_HEADLESS=/usr/bin/VBoxHeadless
  25 
  26 # Do NOT "set -e"
  27 
  28 # PATH should only include /usr/* if it runs after the mountnfs.sh script
  29 PATH=/sbin:/usr/sbin:/bin:/usr/bin
  30 DESC="VirtualBox daemon"
  31 NAME=vm_mgmt
  32 DAEMON=$VBOX_HEADLESS
  33 DAEMON_ARGS=""
  34 PIDFILE=/var/run/$NAME.pid
  35 #SCRIPTNAME=/etc/init.d/$NAME
  36 SCRIPTNAME=/etc/init.d/$NAME
  37 BATTERY_THRESHOLD=3
  38 # Exit if the package is not installed
  39 [ -x "$DAEMON" ] || exit 0
  40 
  41 # Read configuration variable file if it is present
  42 [ -r /etc/default/$NAME ] && . /etc/default/$NAME
  43 
  44 # Load the VERBOSE setting and other rcS variables
  45 . /lib/init/vars.sh
  46 
  47 # LSB log_* functions.
  48 . /lib/lsb/init-functions
  49 
  50 vm_init_list()
  51 {
  52     CHECK_VM_TYPE=0
  53     LIST_VMS=""
  54      # get registered VMs
  55      
  56      if [ "$CHECK_VM_TYPE" -eq "$1" ]
  57      then
  58          LIST_VMS=`sudo -H -u $VBOX_USER $VBOX_MANAGE --nologo list vms | cut -d ' ' -f 1 | tr -d '"'`
  59      else
  60          LIST_VMS=`sudo -H -u $VBOX_USER $VBOX_MANAGE --nologo list runningvms | cut -d ' ' -f 1 | tr -d '"'`
  61      fi
  62    
  63     # check for list of VMs
  64     if [ -z "$VBOX_LIST" ]
  65     then
  66             # all registered VMs for user
  67             VBOX_LIST=$LIST_VMS
  68     else
  69       # check that VMs exist
  70       for VM in $VBOX_LIST
  71       do
  72          case $LIST_VMS in
  73          "$VM")
  74             continue
  75             ;;
  76          *)
  77             log_failure_msg "ERROR: VM '$VM' is not registered!"
  78             exit 1
  79             ;;
  80          esac
  81       done
  82    fi
  83 }
  84 
  85 # get uuid for vm
  86 vm_get_uuid()
  87 {
  88    vm=$1
  89    hwuuid=`sudo -H -u $VBOX_USER $VBOX_MANAGE --nologo showvminfo --machinereadable "$vm" | grep 'hardwareuuid='`
  90    echo $hwuuid | cut -d '=' -f 2 | tr -d '"'
  91 }
  92 
  93 # control running vm
  94 vm_ctrl()
  95 {
  96    sudo -H -u $VBOX_USER $VBOX_MANAGE --nologo controlvm $1 $2 > /dev/null 2>&1
  97 }
  98 
  99 #
 100 # Function that starts the daemon/service
 101 #
 102 do_start()
 103 {
 104     #First do a check on the amount of battery that the system has at this point
 105     BATTERY_LEVEL=0
 106     
 107     #acpi outputs battery info like so: Battery 0: Discharging, 93%, 07:07:03 remaining
 108     BATTERY_LEVEL=`acpi | awk '{print $4}' | tr -d "%,"`
 109     
 110     if [ "$BATTERY_LEVEL" -le "$BATTERY_THRESHOLD" ]
 111     then
 112         log_failure_msg ":( The battery level is low [$BATTERY_LEVEL%] so halting...."
 113         exit 1
 114     fi
 115     
 116     vm_init_list 0
 117     
 118     # Return
 119     #   0 if daemon has been started
 120     #   1 if daemon was already running
 121     #   2 if daemon could not be started
 122     RETVAL=0
 123     
 124     VM_EXISTS=0
 125     FALSE=0
 126     TRUE=1
 127     
 128     #Internal function that will "safely" a VM or VMS. Function takes one.. 
 129     #argument i.e. the VM name and attempts to start that VM
 130     start_vm()
 131     {
 132         VM=$1
 133         VM_UUID=`vm_get_uuid $VM`
 134         VM_PIDFILE="$PIDFILE.$VM_UUID"
 135         VM_DAEMON="$DAEMON"
 136         VM_DAEMON_ARGS="$DAEMON_ARGS --startvm $VM_UUID"
 137           
 138         log_action_begin_msg "Starting VM '$1'"
 139           
 140         # test for running VM
 141         USER=$VBOX_USER LOGNAME=$VBOX_USER start-stop-daemon \
 142             --start \
 143             --quiet \
 144             --pidfile $VM_PIDFILE \
 145             --startas $VM_DAEMON \
 146             --test \
 147             > /dev/null
 148           
 149         # VM already running
 150         if [ "$?" != 0 ]
 151         then
 152             # report VM is running
 153             log_warning_msg "VM '$1' already running"
 154             [ "$RETVAL" = 0 ] && RETVAL=1
 155             continue
 156         fi
 157       
 158         # start VM
 159         USER=$VBOX_USER LOGNAME=$VBOX_USER start-stop-daemon \
 160          --start \
 161          --quiet \
 162          --pidfile $VM_PIDFILE \
 163          --make-pidfile \
 164          --background \
 165          --chuid $VBOX_USER \
 166          --startas $VM_DAEMON \
 167          -- $VM_DAEMON_ARGS
 168           
 169      log_action_end_msg "$?"
 170           
 171      # check if start failed
 172      if [ "$?" != 0 ]
 173      then
 174          # report error
 175          log_failure_msg "Error starting VM '$VM' :("
 176          RETVAL=2
 177      fi
 178       
 179      RETVAL="$?"
 180             
 181      log_action_end_msg "$RETVAL"
 182     exit 0
 183     }
 184     
 185     if [ -n "$1" ]
 186     then
 187         for VM in $VBOX_LIST
 188         do
 189             if [ "$VM" = "$1" ]
 190             then
 191                 VM_EXISTS=1
 192             fi
 193         done
 194         
 195         if [ "$VM_EXISTS" -eq "$TRUE" ]
 196         then
 197             start_vm $1 
 198         else
 199             log_failure_msg "VM $1 is not a registered VM"
 200             echo "Enter one VM name from the list below[VM names are case sensitive];"
 201             
 202             for VM_1 in $VBOX_LIST
 203             do
 204                 echo "$VM_1"
 205             done
 206             exit 1
 207         fi
 208         
 209         VM_EXISTS=0
 210         check_battery
 211         return
 212     fi
 213    
 214     # Start all VMs
 215     for VM in $VBOX_LIST
 216     do
 217         start_vm $VM
 218     done
 219    
 220    if [ "$RETVAL" -lt 2 ]
 221    then
 222       log_daemon_msg "VirtualBox daemon started successfully"
 223    else
 224       log_daemon_msg "VirtualBox daemon started with errors"
 225    fi
 226    
 227    check_battery
 228    
 229    return "$RETVAL"
 230 }
 231 
 232 #
 233 # Function that stops the daemon/service
 234 #
 235 do_stop()
 236 {
 237    vm_init_list 1
 238    
 239    # Return
 240    #   0 if daemon has been stopped
 241    #   1 if daemon was already stopped
 242    #   2 if daemon could not be stopped
 243    #   other if a failure occurred
 244    RETVAL=0
 245     VM_EXISTS=0
 246     FALSE=0
 247     TRUE=1
 248     
 249    #Function "safely" stops and running VM instance. Call this function in a 
 250    #loop to stop all running VM instances (Not the best way but still good)
 251    stop_vm()
 252    {
 253        VM=$1
 254        VM_UUID=`vm_get_uuid $VM`
 255        VM_PIDFILE="$PIDFILE.$VM_UUID"
 256       
 257        log_action_begin_msg "Stopping VM '$VM'"
 258       
 259        # try savestate halt
 260        vm_ctrl $VM savestate
 261       
 262        # stop daemon
 263       USER=$VBOX_USER LOGNAME=$VBOX_USER start-stop-daemon \
 264          --stop \
 265          --quiet \
 266          --retry=TERM/30/KILL/5 \
 267          --pidfile $VM_PIDFILE
 268       
 269       case "$?" in
 270       0)
 271          log_action_end_msg 0
 272          ;;
 273       1)
 274          log_warning_msg "VM '$VM' already stopped"
 275          [ "$RETVAL" = 0 ] && RETVAL=1
 276          ;;
 277       2)
 278          log_action_end_msg 1
 279          log_failure_msg "ERROR: Could not stop VM '$VM'"
 280          RETVAL=2
 281          continue
 282          ;;
 283       esac
 284       
 285       rm -f $VM_PIDFILE
 286    }
 287    
 288    if [ -n "$1" ]
 289     then
 290         for VM in $VBOX_LIST
 291         do
 292             if [ "$VM" = "$1" ]
 293             then
 294                 VM_EXISTS=1
 295             fi
 296         done
 297         
 298         if [ "$VM_EXISTS" -eq "$TRUE" ]
 299         then
 300             stop_vm $1  
 301         else
 302             log_failure_msg "VM $1 is not a registered VM"
 303             echo "Enter the VM name from the list of running VMS below;"
 304             
 305             for VM_1 in $VBOX_LIST
 306             do
 307                 echo "$VM_1"
 308             done
 309             
 310             exit 1
 311         fi
 312         
 313         VM_EXISTS=0
 314         return
 315     fi
 316    
 317    for VM in $VBOX_LIST
 318    do
 319       stop_vm $VM
 320    done
 321    
 322    if [ "$RETVAL" -lt 2 ]
 323    then
 324       log_daemon_msg "VirtualBox daemon stopped successfully"
 325    else
 326       log_daemon_msg "VirtualBox daemon stopped with errors"
 327    fi
 328    
 329    return "$RETVAL"
 330 }
 331 
 332 #
 333 # Function that sends a SIGHUP to the daemon/service
 334 #
 335 do_reload() {
 336    #
 337    # If the daemon can reload its configuration without
 338    # restarting (for example, when it is sent a SIGHUP),
 339    # then implement that here.
 340    #
 341    start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
 342    return 0
 343 }
 344 
 345 check_battery() 
 346 {
 347     BATTERY_OK=true
 348     BATTERY_LEVEL=0
 349 
 350     while [ $BATTERY_OK ]
 351     do
 352         BATTERY_LEVEL=`acpi | awk '{print $4}' | tr -d "%,"`
 353         sleep 5
 354 
 355         if [ $BATTERY_LEVEL -le $BATTERY_THRESHOLD ]
 356         then
 357             echo "Low Battery! Halting any running VMs" | wall
 358             do_stop
 359             BATTERY_OK=false
 360             log_warning_msg "Battery is critically low: $BATTERY_LEVEL%"
 361         fi
 362     done
 363 }
 364 
 365 case "$1" in
 366   start)
 367    log_daemon_msg "Starting $DESC" "$NAME"
 368    do_start $2
 369    case "$?" in
 370       0|1) log_end_msg 0 ;;
 371       2) log_end_msg 1 ;;
 372    esac
 373    ;;
 374   stop)
 375    log_daemon_msg "Stopping $DESC" "$NAME"
 376    do_stop $2
 377    case "$?" in
 378       0|1) log_end_msg 0 ;;
 379       2) log_end_msg 1 ;;
 380    esac
 381    ;;
 382   status)
 383        status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
 384        ;;
 385   #reload|force-reload)
 386    #
 387    # If do_reload() is not implemented then leave this commented out
 388    # and leave 'force-reload' as an alias for 'restart'.
 389    #
 390    #log_daemon_msg "Reloading $DESC" "$NAME"
 391    #do_reload
 392    #log_end_msg $?
 393    #;;
 394   restart|force-reload)
 395    #
 396    # If the "reload" option is implemented then remove the
 397    # 'force-reload' alias
 398    #
 399    log_daemon_msg "Restarting $DESC" "$NAME"
 400    do_stop
 401    case "$?" in
 402      0|1)
 403       do_start $2
 404       case "$?" in
 405          0) log_end_msg 0 ;;
 406          1) log_end_msg 1 ;; # Old process is still running
 407          *) log_end_msg 1 ;; # Failed to start
 408       esac
 409       ;;
 410      *)
 411         # Failed to stop
 412       log_end_msg 1
 413       ;;
 414    esac
 415    ;;
 416   *)
 417    
 418    echo "Usage: $SCRIPTNAME {start [VM]|stop [VM]|status|restart [VM]|force-reload [VM]}" >&2
 419    echo "\t Please note that 'start' [VM] indicates that the argument VM is optional f.g. you can write start OMRS"
 420    exit 3
 421    ;;
 422 esac
 423 
 424 :
 425 

Thursday, 7 October 2010

Kismet: HOW TO

Kismet is one of the ultra modern wireless sniffers. It can and should be used in together with others such as aircrack-ng, airodump, airdecap, airreplay and others. I view these applications as complementary rather than competing. Windows users have netstumbler which in my view may not exactly match up with the above tools especially if they are all used together. Kismet works on any NIC (at least I think) that supports raw monitoring (rfmon). It should not have any problems with IEEE 802.11a, b, g ,n traffic.

On Linux Ubuntu, you have to install kismet using the normal ways i.e
sudo apt-get install kismet
sudo aptitude install kismet

Then comes the configuration which may be simple for others and a hair pulling experience for others. Mine was a mixture of both; After installing kismet, You will have to make configurations to the kismet.conf file which if you installed using the sudo apt-get install kismet method, should be somehere here; /etc/kismet/kismet.conf.

A good idea is to first backup that file (perhaps in the same directory).
cp -v /etc/kismet/kismet.conf /etc/kismet/kismet.conf.backup OR
cp -v /etc/kismet/kismet.conf /etc/kismet/kismet.conf~

That's incase you screw things up in that file.

Then there are primarily two things that you have to change; i.e.
#suiduser=your_user_here

Uncomment that line and enter your username where the "your_user_here" section is. If you are unsure of your username (yea, it happens), on shell type shell$ whoami and the shell will tell you who you are!

Now that you are through with the first part of configuring kismet, the second and somewhat disturbing section is next.

The second section mainly deals with how to configure the source/ interface that kismet will use for monitoring the wireless signals.

Next search for this section

# YOU MUST CHANGE THIS TO BE THE SOURCE YOU WANT TO USE
source=none,none,addme
The first none is the driver that is used by your wireless card hardware. If you are not sure, you can use this command to determine it, sudo lshw -C network. This is an example output of the above command;

marcusOfGearsOfWar@gears:~$ sudo lshw -C network
  *-network               
       description: Wireless interface
       product: AR9285 Wireless Network Adapter (PCI-Express)
       vendor: Atheros Communications Inc.
       physical id: 0
       bus info: pci@0000:03:00.0
       logical name: wlan0
       version: 01
       serial: 1c:4b:d6:55:da:5f
       width: 64 bits
       clock: 33MHz
       capabilities: pm msi pciexpress bus_master cap_list logical wireless
       configuration: broadcast=yes driver=ath9k latency=0 multicast=yes promiscuous=yes wireless=IEEE 802.11bgn
       resources: irq:17 memory:feaf0000-feafffff

The important section in this verbose output is the driver section (in bold) i.e driver=ath9k

The output above is from an Atheros AR9285 Wireless NIC. It clearly displays the driver as ath9k.  However this is interesting because kismet does not like that particular driver. It prefers ath5k. ath9k uses the same capture code as ath5k (I think, just wondering why it shouldn't be used).

Anyhow, if your driver is ath9k, it won't work with kismet (as of now 2010-10-07) unless you pull something incredible off. You should instead use ath5k (that is only if your driver is ath9k) but any other driver as reported by lshw -C network command should work without any hiccups.

Then the second none in source=none,none,addme is the name that your OS uses for the wireless card.
Trying iwconfig should return your wireless card's nickname eg. wlan0

Then the third parameter addme is used for logging purposes. So any name can do.

I installed kismet from ubuntu software repository. Using this method of installation makes kismet love user "root". It will hate anyone else who is not root.

So to fire up kismet, type, sudo kismet and you are "good to go-go" (Spyro Gyra) It will start reporting which wireless networks are available.

Remember, you can get the help menu by typing 'h'. However you can get to the help menu only if you first get rid of the welcome message. If kismet displays a welcome message, you can get rid of that message by pressing the space bar (Just once can do).

ONE IMPORTANT NOTE IS THAT YOU WIRELESS CARD WILL IMMEDIATELY ENTER MONITORING MODE AND WILL DISSOCIATE FROM ANY APs IT HAD EARLIER ASSOCIATED WITH.
So you cannot connect to a wireless network when your card is in monitoring mode.

One small nuance is that after you quit kismet (using the Capital Q), kismet's dumb enough to leave your wireless NIC in monitoring mode (not the clean managed mode it was in before you fired kismet up).

However, don't despair. Restarting your machine is one option. But another quick option is using doing this;

sudo ifconfig wlan0 down
sudo iwconfig wlan0 mode managed
sudo ifconfig wlan0 up

That should sort things out.

If you are interested in listening from the horse's mouth, just go direct to the source

Have a nice day!!!!!

Tuesday, 28 September 2010

Stay Hungry Stay Foolish

'You've got to find what you love,' Jobs says
This is the text of the Commencement address by Steve Jobs, CEO of Apple Computer and of Pixar Animation Studios, delivered on June 12, 2005.

I am honored to be with you today at your commencement from one of the finest universities in the world. I never graduated from college. Truth be told, this is the closest I've ever gotten to a college graduation. Today I want to tell you three stories from my life. That's it. No big deal. Just three stories.

The first story is about connecting the dots.

I dropped out of Reed College after the first 6 months, but then stayed around as a drop-in for another 18 months or so before I really quit. So why did I drop out?

It started before I was born. My biological mother was a young, unwed college graduate student, and she decided to put me up for adoption. She felt very strongly that I should be adopted by college graduates, so everything was all set for me to be adopted at birth by a lawyer and his wife. Except that when I popped out they decided at the last minute that they really wanted a girl. So my parents, who were on a waiting list, got a call in the middle of the night asking: "We have an unexpected baby boy; do you want him?" They said: "Of course." My biological mother later found out that my mother had never graduated from college and that my father had never graduated from high school. She refused to sign the final adoption papers. She only relented a few months later when my parents promised that I would someday go to college.

And 17 years later I did go to college. But I naively chose a college that was almost as expensive as Stanford, and all of my working-class parents' savings were being spent on my college tuition. After six months, I couldn't see the value in it. I had no idea what I wanted to do with my life and no idea how college was going to help me figure it out. And here I was spending all of the money my parents had saved their entire life. So I decided to drop out and trust that it would all work out OK. It was pretty scary at the time, but looking back it was one of the best decisions I ever made. The minute I dropped out I could stop taking the required classes that didn't interest me, and begin dropping in on the ones that looked interesting.

It wasn't all romantic. I didn't have a dorm room, so I slept on the floor in friends' rooms, I returned coke bottles for the 5¢ deposits to buy food with, and I would walk the 7 miles across town every Sunday night to get one good meal a week at the Hare Krishna temple. I loved it. And much of what I stumbled into by following my curiosity and intuition turned out to be priceless later on. Let me give you one example:

Reed College at that time offered perhaps the best calligraphy instruction in the country. Throughout the campus every poster, every label on every drawer, was beautifully hand calligraphed. Because I had dropped out and didn't have to take the normal classes, I decided to take a calligraphy class to learn how to do this. I learned about serif and san serif typefaces, about varying the amount of space between different letter combinations, about what makes great typography great. It was beautiful, historical, artistically subtle in a way that science can't capture, and I found it fascinating.

None of this had even a hope of any practical application in my life. But ten years later, when we were designing the first Macintosh computer, it all came back to me. And we designed it all into the Mac. It was the first computer with beautiful typography. If I had never dropped in on that single course in college, the Mac would have never had multiple typefaces or proportionally spaced fonts. And since Windows just copied the Mac, its likely that no personal computer would have them. If I had never dropped out, I would have never dropped in on this calligraphy class, and personal computers might not have the wonderful typography that they do. Of course it was impossible to connect the dots looking
forward when I was in college. But it was very, very clear looking backwards ten years later.

Again, you can't connect the dots looking forward; you can only connect them looking backwards. So you have to trust that the dots will somehow connect in your future. You have to trust in something — your gut, destiny, life, karma, whatever. This approach has never let me down, and it has made all the difference in my life.

My second story is about love and loss.

I was lucky — I found what I loved to do early in life. Woz and I started Apple in my parents garage when I was 20. We worked hard, and in 10 years Apple had grown from just the two of us in a garage into a $2 billion company with over 4000 employees. We had just released our finest creation — the Macintosh — a year earlier, and I had just turned 30. And then I got fired. How can you get fired from a company you started? Well, as Apple grew we hired someone who I thought was very talented to run the company with me, and for the first year or so things went well. But then our visions of the future began to diverge and eventually we had a falling out. When we did, our Board of Directors sided with
him. So at 30 I was out. And very publicly out. What had been the focus of my entire adult life was gone, and it was devastating.

I really didn't know what to do for a few months. I felt that I had let the previous generation of entrepreneurs down - that I had dropped the baton as it was being passed to me. I met with David Packard and Bob Noyce and tried to apologize for screwing up so badly. I was a very public failure, and I even thought about  running away from the valley. But something slowly began to dawn on me —
I still loved what I did. The turn of events at Apple had not changed that one bit. I had been rejected, but I was still in love. And so I decided to start over. I didn't see it then, but it turned out that getting fired from Apple was the best thing that could have ever happened to me. The heaviness of being successful was replaced by the lightness of being a beginner again, less sure about everything. It freed me to enter one of the most creative periods of my life.

During the next five years, I started a company named NeXT, another company named Pixar, and fell
in love with an amazing woman who would become my wife. Pixar went on to create the worlds first
computer animated feature film, Toy Story, and is now the most successful animation studio in the
world. In a remarkable turn of events, Apple bought NeXT, I returned to Apple, and the technology we
developed at NeXT is at the heart of Apple's current renaissance. And Laurene and I have a wonderful
family together.
I'm pretty sure none of this would have happened if I hadn't been fired from Apple. It was awful tasting
medicine, but I guess the patient needed it. Sometimes life hits you in the head with a brick. Don't lose
faith. I'm convinced that the only thing that kept me going was that I loved what I did. You've got to
find what you love. And that is as true for your work as it is for your lovers. Your work is going to fill a
large part of your life, and the only way to be truly satisfied is to do what you believe is great work.
And the only way to do great work is to love what you do. If you haven't found it yet, keep looking.
Don't settle. As with all matters of the heart, you'll know when you find it. And, like any great
relationship, it just gets better and better as the years roll on. So keep looking until you find it. Don't
settle.
My third story is about death.
When I was 17, I read a quote that went something like: "If you live each day as if it was your last,
someday you'll most certainly be right." It made an impression on me, and since then, for the past 33
years, I have looked in the mirror every morning and asked myself: "If today were the last day of my
life, would I want to do what I am about to do today?" And whenever the answer has been "No" for too
many days in a row, I know I need to change something.
Remembering that I'll be dead soon is the most important tool I've ever encountered to help me make
the big choices in life. Because almost everything — all external expectations, all pride, all fear of
embarrassment or failure - these things just fall away in the face of death, leaving only what is truly
important. Remembering that you are going to die is the best way I know to avoid the trap of thinking
you have something to lose. You are already naked. There is no reason not to follow your heart.
About a year ago I was diagnosed with cancer. I had a scan at 7:30 in the morning, and it clearly
showed a tumor on my pancreas. I didn't even know what a pancreas was. The doctors told me this was
almost certainly a type of cancer that is incurable, and that I should expect to live no longer than three
to six months. My doctor advised me to go home and get my affairs in order, which is doctor's code for
prepare to die. It means to try to tell your kids everything you thought you'd have the next 10 years to
tell them in just a few months. It means to make sure everything is buttoned up so that it will be as easy
as possible for your family. It means to say your goodbyes.
I lived with that diagnosis all day. Later that evening I had a biopsy, where they stuck an endoscope
down my throat, through my stomach and into my intestines, put a needle into my pancreas and got a
few cells from the tumor. I was sedated, but my wife, who was there, told me that when they viewed
the cells under a microscope the doctors started crying because it turned out to be a very rare form of
pancreatic cancer that is curable with surgery. I had the surgery and I'm fine now.
This was the closest I've been to facing death, and I hope its the closest I get for a few more decades.
Having lived through it, I can now say this to you with a bit more certainty than when death was a
useful but purely intellectual concept:
No one wants to die. Even people who want to go to heaven don't want to die to get there. And yet
death is the destination we all share. No one has ever escaped it. And that is as it should be, because
Death is very likely the single best invention of Life. It is Life's change agent. It clears out the old to
make way for the new. Right now the new is you, but someday not too long from now, you will
gradually become the old and be cleared away. Sorry to be so dramatic, but it is quite true.
Your time is limited, so don't waste it living someone else's life. Don't be trapped by dogma — which is
living with the results of other people's thinking. Don't let the noise of others' opinions drown out your
own inner voice. And most important, have the courage to follow your heart and intuition. They
somehow already know what you truly want to become. Everything else is secondary.
When I was young, there was an amazing publication called The Whole Earth Catalog, which was one
of the bibles of my generation. It was created by a fellow named Stewart Brand not far from here in
Menlo Park, and he brought it to life with his poetic touch. This was in the late 1960's, before personal
computers and desktop publishing, so it was all made with typewriters, scissors, and polaroid cameras.
It was sort of like Google in paperback form, 35 years before Google came along: it was idealistic, and
overflowing with neat tools and great notions.
Stewart and his team put out several issues of The Whole Earth Catalog, and then when it had run its
course, they put out a final issue. It was the mid-1970s, and I was your age. On the back cover of their
final issue was a photograph of an early morning country road, the kind you might find yourself
hitchhiking on if you were so adventurous. Beneath it were the words: "Stay Hungry. Stay Foolish." It
was their farewell message as they signed off. Stay Hungry. Stay Foolish. And I have always wished
that for myself. And now, as you graduate to begin anew, I wish that for you.
Stay Hungry. Stay Foolish.
Thank you all very much.
Related Information

Wednesday, 17 March 2010

Remove files or directories

`rm' removes each given FILE. By default, it does not remove directories. Synopsis:

rm [OPTION]... [FILE]...

If the `-I' or `--interactive=once' option is given, and there are more than three files or the `-r', `-R', or `--recursive' are given,  then `rm' prompts the user for whether to proceed with the entire operation. If the response is not affirmative, the entire command is aborted.

Otherwise, if a file is unwritable, standard input is a terminal, and the `-f' or `--force' option is not given, or the `-i' or `--interactive=always' option _is_ given, `rm' prompts the user for whether to remove the file. If the response is not affirmative, the file is skipped. Any attempt to remove a file whose last file name component is `.' or `..' is rejected without any prompting. _Warning_: If you use `rm' to remove a file, it is usually possible to recover the contents of that file. If you want more assurance that the contents are truly unrecoverable, consider using `shred'.

The program accepts the following options. Also see *note Common options::.

`-f'
`--force'

Ignore nonexistent files and never prompt the user. Ignore any previous `--interactive' (`-i') option.

`-i'
Prompt whether to remove each file. If the response is not affirmative, the file is skipped. Ignore any previous `--force'  (`-f') option. Equivalent to `--interactive=always'.

`-I'
Prompt once whether to proceed with the command, if more than three files are named or if a recursive removal is requested. Ignore any previous `--force' (`-f') option. Equivalent to `--interactive=once'.

`--interactive [=WHEN]'
Specify when to issue an interactive prompt. WHEN may be omitted, or one of:
* never - Do not prompt at all.
* once - Prompt once if more than three files are named or if a
* always - Prompt for every file being removed. Equivalent to
`-i'.
`--interactive' with no WHEN is equivalent to `--interactive=always'.
`--one-file-system'

When removing a hierarchy recursively, skip any directory that is on a file system different from that of the corresponding command line argument. This option is useful when removing a build "chroot" hierarchy,
which normally contains no valuable data. However, it is not uncommon to bind-mount `/home' into such a hierarchy, to make it easier to use one's start-up file. The catch is that it's easy to forget to unmount `/home'. Then, when you use `rm -rf' to remove your normally throw-away chroot, that command will remove
everything under `/home', too. Use the `--one-file-system' option, and it will warn about and skip directories on other file systems. Of course, this will not save your `/home' if it and your chroot happen to be on the same file system.

`--preserve-root'
Fail upon any attempt to remove the root directory, `/', when used with the `--recursive' option. This is the default behavior. *Note Treating / specially::.
`--no-preserve-root'
Do not treat `/' specially when removing recursively. This option is not recommended unless you really want to remove all the files on your computer. *Note Treating / specially::.

`-r'
`-R'
`--recursive'
Remove the listed directories and their contents recursively.

`-v'
`--verbose'
Print the name of each file before removing it.


One common question is how to remove files whose names begin with a `-'. GNU `rm', like every program that uses the `getopt' function to parse its arguments, lets you use the `--' option to indicate that all following arguments are non-options. To remove a file called `-f' in the current directory, you could type either:

rm -- -f

or:

rm ./-f

The Unix `rm' program's use of a single `-' for this purpose predates the development of the getopt standard syntax.  An exit status of zero indicates success, and a nonzero value indicates failure.

Explicitly Specifying Welcome Pages

A welcome page refers to the page that appears when you specify a URL that is a directory. On UNIX systems, an example is /usr/local/ In web applications, this translates to http://localhost:8080/, http://localhost:8080/restricted/ and on and on and on.

The servlet specification states that the server should first locate the index.jsp page. If unavailable, then the index.html page. Now the servlet specification does not specify what the servlet/ web container should do if the index.jsp and/ or the index.html pages are unavailable. The next action of the server is therefore server specific. Some servlet containers simply throw an HTTP 404 error, others list the contents of that directory. Such divergent behaviour of servlet containers from the various vendors may make your application behave differently on different containers (much like the behaviour of programs running on different platforms such as UNIX and Windows without any code changes that were developed using other programming languages such as C). This definitely makes your web application much less portable.


The purpose of specifying the welcome pages in the web.xml file is to ensure uniform behaviour of your web application across all these different containers keeping the promise of the Java programming language and platform of Write Once and Run Anywhere (WORA). There are ways in which such diverse behaviour of the web servers can be overcome.

  1. One way is to explicitly create the index.jsp file in that directory or the index.html page or both.

  2. The other way is to specify the welcome page using the welcome tags of the web.xml file.
The first approach is self explanatory. We will discuss the second approach instead.

In order to specify the resource that should be returned when a visitor of your site or user of your web app, you should consider the <welcome-file-list> tag of the web.xml file. This tag has an opening and closing tag. Do not forget the closing tag How this works is like so;

1:                 <welcome-file-list>
2: <welcome-file>firstPage.jsp</welcome-file>
3: <welcome-file>secondPage.html</welcome-file>
4: <welcome-file>thirdPage.jsp</welcome-file>
5: </welcome-file-list>

The servlet container will be obliged to display firstPage.jsp first; if firstPage.jsp suddenly becomes unavailable for some sinister reason, then secondPage.html will be displayed instead. If secondPage conspires to go AWOL as well, the server loads up thirdPage.jsp. This helps in making issues explicit and not having to rely on server specific behaviour which in some cases may not be merciful. Consider the situation where the index.jsp and index.html files are unavailable and the server displays the contents of the directory as if it were on ftp. Also the server throwing a HTTP 404 Error. Such behaviour is definitely unacceptable.


Friday, 24 July 2009

What is Intelligence - Isaac Asimov

Hi all, This article is about a question by Isaac Asimov (whose book was based upon in the making of iRobot, - Will Smith). Quite stimulating to read.

What is intelligence, anyway? When I was in the army, I received the kind of aptitude test that all soldiers took and, against a normal of 100, scored 160. No one at the base had ever seen a figure like that, and for two hours they made a big fuss over me. (It didn't mean anything. The next day I was still a buck private with KP - kitchen police - as my highest duty.)

All my life I've been registering scores like that, so that I have the complacent feeling that I'm highly intelligent, and I expect other people to think so too. Actually, though, don't such scores simply mean that I am very good at answering the type of academic questions that are considered worthy of answers by people who make up the intelligence tests - people with intellectual bents similar to mine?

For instance, I had an auto-repair man once, who, on these intelligence tests, could not possibly have scored more than 80, by my estimate. I always took it for granted that I was far more intelligent than he was. Yet, when anything went wrong with my car I hastened to him with it, watched him anxiously as he explored its vitals, and listened to his pronouncements as though they were divine oracles - and he always fixed my car.

Well, then, suppose my auto-repair man devised questions for an intelligence test. Or suppose a carpenter did, or a farmer, or, indeed, almost anyone but an academician. By every one of those tests, I'd prove myself a moron, and I'd be a moron, too. In a world where I could not use my academic training and my verbal talents but had to do something intricate or hard, working with my hands, I would do poorly. My intelligence, then, is not absolute but is a function of the society I live in and of the fact that a small subsection of that society has managed to foist itself on the rest as an arbiter of such matters.

Consider my auto-repair man, again. He had a habit of telling me jokes whenever he saw me. One time he raised his head from under the automobile hood to say: "Doc, a deaf-and-mute guy went into a hardware store to ask for some nails. He put two fingers together on the counter and made hammering motions with the other hand. The clerk brought him a hammer. He shook his head and pointed to the two fingers he was hammering. The clerk brought him nails. He picked out the sizes he wanted, and left. Well, doc, the next guy who came in was a blind man. He wanted scissors. How do you suppose he asked for them?"

Indulgently, I lifted by right hand and made scissoring motions with my first two fingers. Whereupon my auto-repair man laughed raucously and said, "Why, you dumb jerk, He used his voice and asked for them." Then he said smugly, "I've been trying that on all my customers today." "Did you catch many?" I asked. "Quite a few," he said, "but I knew for sure I'd catch you." "Why is that?" I asked. "Because you're so goddamned educated, doc, I knew you couldn't be very smart."

Friday, 23 January 2009

Working with Microsoft Ofice Excel Files

Want to use HSSF and XSSF read and write spreadsheets in a hurry? This guide is for you. If you're after more in-depth coverage of the HSSF and XSSF user-APIs, please consult the HOWTO guide as it contains actual descriptions of how to use this stuff.





New Workbook

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

    Workbook wb = new XSSFWorkbook();
    FileOutputStream fileOut = new FileOutputStream("workbook.xlsx");
    wb.write(fileOut);
    fileOut.close();
                    

New Sheet

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

Creating Cells

Workbook wb = new HSSFWorkbook();
    //Workbook wb = new XSSFWorkbook();
    CreationHelper createHelper = wb.getCreationHelper();
    Sheet sheet = wb.createSheet("new sheet");

    // Create a row and put some cells in it. Rows are 0 based.
    Row row = sheet.createRow((short)0);
    // Create a cell and put a value in it.
    Cell cell = row.createCell(0);
    cell.setCellValue(1);

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

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

Creating Date Cells

Workbook wb = new HSSFWorkbook();
    //Workbook wb = new XSSFWorkbook();
    CreationHelper createHelper = wb.getCreationHelper();
    Sheet sheet = wb.createSheet("new sheet");

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

    // Create a cell and put a date value in it.  The first cell is not styled
    // as a date.
    Cell cell = row.createCell(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.
    CellStyle cellStyle = wb.createCellStyle();
    cellStyle.setDataFormat(
        createHelper.createDataFormat().getFormat("m/d/yy h:mm"));
    cell = row.createCell(1);
    cell.setCellValue(new Date());
    cell.setCellStyle(cellStyle);

    //you can also set date as java.util.Calendar
    cell = row.createCell(2);
    cell.setCellValue(Calendar.getInstance());
    cell.setCellStyle(cellStyle);

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

Working with different types of cells

Workbook wb = new HSSFWorkbook();
    Sheet sheet = wb.createSheet("new sheet");
    Row row = sheet.createRow((short)2);
    row.createCell(0).setCellValue(1.1);
    row.createCell(1).setCellValue(new Date());
    row.createCell(2).setCellValue(Calendar.getInstance());
    row.createCell(3).setCellValue("a string");
    row.createCell(4).setCellValue(true);
    row.createCell(5).setCellType(HSSFCell.CELL_TYPE_ERROR);

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

Demonstrates various alignment options

public static void main(String[] args)  throws Exception {
        Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook();

        Sheet sheet = wb.createSheet();
        Row row = sheet.createRow((short) 2);
        row.setHeightInPoints(30);

        createCell(wb, row, (short) 0, XSSFCellStyle.ALIGN_CENTER, XSSFCellStyle.VERTICAL_BOTTOM);
        createCell(wb, row, (short) 1, XSSFCellStyle.ALIGN_CENTER_SELECTION, XSSFCellStyle.VERTICAL_BOTTOM);
        createCell(wb, row, (short) 2, XSSFCellStyle.ALIGN_FILL, XSSFCellStyle.VERTICAL_CENTER);
        createCell(wb, row, (short) 3, XSSFCellStyle.ALIGN_GENERAL, XSSFCellStyle.VERTICAL_CENTER);
        createCell(wb, row, (short) 4, XSSFCellStyle.ALIGN_JUSTIFY, XSSFCellStyle.VERTICAL_JUSTIFY);
        createCell(wb, row, (short) 5, XSSFCellStyle.ALIGN_LEFT, XSSFCellStyle.VERTICAL_TOP);
        createCell(wb, row, (short) 6, XSSFCellStyle.ALIGN_RIGHT, XSSFCellStyle.VERTICAL_TOP);

        // Write the output to a file
        FileOutputStream fileOut = new FileOutputStream("xssf-align.xlsx");
        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 halign the horizontal alignment for the cell.
     */
    private static void createCell(Workbook wb, Row row, short column, short halign, short valign) {
        Cell cell = row.createCell(column);
        cell.setCellValue(new XSSFRichTextString("Align It"));
        CellStyle cellStyle = wb.createCellStyle();
        cellStyle.setAlignment(halign);
        cellStyle.setVerticalAlignment(valign);
        cell.setCellStyle(cellStyle);
    }
                    

Working with borders

Workbook wb = new HSSFWorkbook();
    Sheet sheet = wb.createSheet("new sheet");

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

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

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

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

Iterate over rows and cells

Sometimes, you'd like to just iterate over all the rows in a sheet, or all the cells in a row. This is possible with a simple for loop.
Luckily, this is very easy. Row defines a CellIterator inner class to handle iterating over the cells (get one with a call to row.cellIterator()), and Sheet provides a rowIterator() method to give an iterator over all the rows.
Alternately, Sheet and Row both implement java.lang.Iterable, so if you're using Java 1.5, you can simply take advantage of the built in "foreach" support - see below.
Sheet sheet = wb.getSheetAt(0);
 for (Iterator rit = sheet.rowIterator(); rit.hasNext(); ) {
  Row row = (Row)rit.next();
  for (Iterator cit = row.cellIterator(); cit.hasNext(); ) {
   Cell cell = (Cell)cit.next();
   // Do something here
  }
 }
    
HSSFSheet sheet = wb.getSheetAt(0);
 for (Iterator rit = (Iterator)sheet.rowIterator(); rit.hasNext(); ) {
  HSSFRow row = rit.next();
  for (Iterator cit = (Iterator)row.cellIterator(); cit.hasNext(); ) {
   HSSFCell cell = cit.next();
   // Do something here
  }
 }
    

Iterate over rows and cells using Java 1.5 foreach loops

Sometimes, you'd like to just iterate over all the rows in a sheet, or all the cells in a row. If you are using Java 5 or later, then this is especially handy, as it'll allow the new foreach loop support to work.
Luckily, this is very easy. Both Sheet and Row implement java.lang.Iterable to allow foreach loops. For Row this allows access to the CellIterator inner class to handle iterating over the cells, and for Sheet gives the rowIterator() to iterator over all the rows.
Sheet sheet = wb.getSheetAt(0);
 for (Row row : sheet) {
  for (Cell cell : row) {
   // Do something here
  }
 }
    

Getting the cell contents

To get the contents of a cell, you first need to know what kind of cell it is (asking a string cell for its numeric contents will get you a NumberFormatException for example). So, you will want to switch on the cell's type, and then call the appropriate getter for that cell.
In the code below, we loop over every cell in one sheet, print out the cell's reference (eg A3), and then the cell's contents.
// import org.apache.poi.ss.usermodel.*;

Sheet sheet1 = wb.getSheetAt(0);
for (Row row : sheet1) {
 for (Cell cell : row) {
  CellReference cellRef = new CellReference(row.getRowNum(), cell.getCellNum());
  System.out.print(cellRef.formatAsString());
  System.out.print(" - ");
  
  switch(cell.getCellType()) {
      case Cell.CELL_TYPE_STRING:
        System.out.println(cell.getRichStringCellValue().getString());
        break;
      case Cell.CELL_TYPE_NUMERIC:
        if(DateUtil.isCellDateFormatted(cell)) {
          System.out.println(cell.getDateCellValue());
        } else {
          System.out.println(cell.getNumericCellValue());
        }
        break;
      case Cell.CELL_TYPE_BOOLEAN:
        System.out.println(cell.getBooleanCellValue());
        break;
      case Cell.CELL_TYPE_FORMULA:
        System.out.println(cell.getCellFormula());
        break;
      default:
        System.out.println();
  }
 }
}
    

Text Extraction

For most text extraction requirements, the standard ExcelExtractor class should provide all you need.
InputStream inp = new FileInputStream("workbook.xls");
 HSSFWorkbook wb = new HSSFWorkbook(new POIFSFileSystem(inp));
 ExcelExtractor extractor = new ExcelExtractor(wb);

 extractor.setFormulasNotResults(true);
 extractor.setIncludeSheetNames(false);
 String text = extractor.getText();
     
For very fancy text extraction, XLS to CSV etc, take a look at /src/scratchpad/examples/src/org/apache/poi/hssf/eventusermodel/examples/XLS2CSVmra.java

Fills and colors

Workbook wb = new XSSFWorkbook();
    Sheet sheet = wb.createSheet("new sheet");

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

    // Aqua background
    CellStyle style = wb.createCellStyle();
    style.setFillBackgroundColor(IndexedColors.AQUA.getIndex());
    style.setFillPattern(CellStyle.BIG_SPOTS);
    Cell 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(IndexedColors.ORANGE.getIndex());
    style.setFillPattern(CellStyle.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();
                    

Merging cells

Workbook wb = new HSSFWorkbook();
    Sheet sheet = wb.createSheet("new sheet");

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

    sheet.addMergedRegion(new CellRangeAddress(
            1, //first row (0-based)
            1, //last row  (0-based)
            1, //first column (0-based)
            2  //last column  (0-based)
    ));

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

Working with fonts

Workbook wb = new HSSFWorkbook();
    Sheet sheet = wb.createSheet("new sheet");

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

    // Create a new font and alter it.
    Font 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.
    CellStyle style = wb.createCellStyle();
    style.setFont(font);

    // Create a cell and put a value in it.
    Cell cell = row.createCell(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();
  
Note, the maximum number of unique fonts in a workbook is limited to 32767 ( the maximum positive short). You should re-use fonts in your apllications instead of creating a font for each cell. Examples:
Wrong:
for (int i = 0; i < 10000; i++) {
            Row row = sheet.createRow(i);
            Cell cell = row.createCell((short) 0);

            CellStyle style = workbook.createCellStyle();
            Font font = workbook.createFont();
            font.setBoldweight(Font.BOLDWEIGHT_BOLD);
            style.setFont(font);
            cell.setCellStyle(style);
        }
Correct:
CellStyle style = workbook.createCellStyle();
        Font font = workbook.createFont();
        font.setBoldweight(Font.BOLDWEIGHT_BOLD);
        style.setFont(font);
        for (int i = 0; i < 10000; i++) {
            Row row = sheet.createRow(i);
            Cell cell = row.createCell((short) 0);
            cell.setCellStyle(style);
        }

Custom colors

HSSF:
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();
                    
XSSF:
XSSFWorkbook wb = new XSSFWorkbook();
    XSSFSheet sheet = wb.createSheet();
    XSSFRow row = sheet.createRow(0);
    XSSFCell cell = row.createCell( 0);
    cell.setCellValue("custom XSSF colors");

    XSSFCellStyle style1 = wb.createCellStyle();
    style1.setFillForegroundColor(new XSSFColor(new java.awt.Color(128, 0, 128)));
    style1.setFillPattern(CellStyle.SOLID_FOREGROUND);
                    

Reading and Rewriting Workbooks

InputStream inp = new FileInputStream("workbook.xls");
    //InputStream inp = new FileInputStream("workbook.xlsx");

    Workbook wb = WorkbookFactory.create(inp);
    Sheet sheet = wb.getSheetAt(0);
    Row row = sheet.getRow(2);
    Cell cell = row.getCell(3);
    if (cell == null)
        cell = row.createCell(3);
    cell.setCellType(Cell.CELL_TYPE_STRING);
    cell.setCellValue("a test");

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

Using newlines in cells

Workbook wb = new XSSFWorkbook();   //or new HSSFWorkbook();
    Sheet sheet = wb.createSheet();

    Row row = sheet.createRow(2);
    Cell cell = row.createCell(2);
    cell.setCellValue("Use \n with word wrap on to create a new line");

    //to enable newlines you need set a cell styles with wrap=true
    CellStyle cs = wb.createCellStyle();
    cs.setWrapText(true);
    cell.setCellStyle(cs);

    //increase row height to accomodate two lines of text
    row.setHeightInPoints((2*sheet.getDefaultRowHeightInPoints()));

    //adjust column width to fit the content
    sheet.autoSizeColumn((short)2);

    FileOutputStream fileOut = new FileOutputStream("ooxml-newlines.xlsx");
    wb.write(fileOut);
    fileOut.close();
                  

Data Formats

Workbook wb = new HSSFWorkbook();
    Sheet sheet = wb.createSheet("format sheet");
    CellStyle style;
    DataFormat format = wb.createDataFormat();
    Row row;
    Cell 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();
                    

Fit Sheet to One Page

Workbook wb = new HSSFWorkbook();
    Sheet sheet = wb.createSheet("format sheet");
    PrintSetup 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();
                    

Set Print Area

Workbook wb = new HSSFWorkbook();
    Sheet sheet = wb.createSheet("Sheet1");
    //sets the print area for the first sheet
    wb.setPrintArea(0, "$A$1:$C$2");
    
    //Alternatively:
    wb.setPrintArea(
            0, //sheet index
            0, //start column
            1, //end column
            0, //start row
            0  //end row
    );

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

Set Page Numbers on Footer

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();
                    

Using the Convenience Functions

The convenience functions live in contrib and provide utility features such as setting borders around merged regions and changing style attributes without explicitly creating new styles.
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();
                    

Shift rows up or down on a sheet

Workbook wb = new HSSFWorkbook();
        Sheet 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);

                    

Set a sheet as selected

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

                    

Set the zoom magnification

The zoom is expressed as a fraction. For example to express a zoom of 75% use 3 for the numerator and 4 for the denominator.
Workbook wb = new HSSFWorkbook();
    Sheet sheet1 = wb.createSheet("new sheet");
    sheet1.setZoom(3,4);   // 75 percent magnification
                    

Splits and freeze panes

There are two types of panes you can create; freeze panes and split panes.
A freeze pane is split by columns and rows. You create a freeze pane using the following mechanism:
sheet1.createFreezePane( 3, 2, 3, 2 );
The first two parameters are the columns and rows you wish to split by. The second two parameters indicate the cells that are visible in the bottom right quadrant.
Split pains appear differently. The split area is divided into four separate work area's. The split occurs at the pixel level and the user is able to adjust the split by dragging it to a new position.
Split panes are created with the following call:
sheet2.createSplitPane( 2000, 2000, 0, 0, Sheet.PANE_LOWER_LEFT );
The first parameter is the x position of the split. This is in 1/20th of a point. A point in this case seems to equate to a pixel. The second parameter is the y position of the split. Again in 1/20th of a point.
The last parameter indicates which pane currently has the focus. This will be one of Sheet.PANE_LOWER_LEFT, PANE_LOWER_RIGHT, PANE_UPPER_RIGHT or PANE_UPPER_LEFT.
Workbook wb = new HSSFWorkbook();
    Sheet sheet1 = wb.createSheet("new sheet");
    Sheet sheet2 = wb.createSheet("second sheet");
    Sheet sheet3 = wb.createSheet("third sheet");
    Sheet 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, Sheet.PANE_LOWER_LEFT );

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

Repeating rows and columns

It's possible to set up repeating rows and columns in your printouts by using the setRepeatingRowsAndColumns() function in the HSSFWorkbook class.
This function Contains 5 parameters. The first parameter is the index to the sheet (0 = first sheet). The second and third parameters specify the range for the columns to repreat. To stop the columns from repeating pass in -1 as the start and end column. The fourth and fifth parameters specify the range for the rows to repeat. To stop the columns from repeating pass in -1 as the start and end rows.
Workbook wb = new HSSFWorkbook();
    Sheet sheet1 = wb.createSheet("new sheet");
    Sheet 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

Example is for headers but applies directly to footers.
Workbook wb = new HSSFWorkbook();
    Sheet sheet = wb.createSheet("new sheet");

    Header 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

POI supports drawing shapes using the Microsoft Office drawing tools. Shapes on a sheet are organized in a hiearchy of groups and and shapes. The top-most shape is the patriarch. This is not visisble on the sheet at all. To start drawing you need to call createPatriarch on the HSSFSheet class. This has the effect erasing any other shape information stored in that sheet. By default POI will leave shape records alone in the sheet unless you make a call to this method.
To create a shape you have to go through the following steps:
  1. Create the patriarch.
  2. Create an anchor to position the shape on the sheet.
  3. Ask the patriarch to create the shape.
  4. Set the shape type (line, oval, rectangle etc...)
  5. Set any other style details converning the shape. (eg: line thickness, etc...)
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
    a = new HSSFClientAnchor( 0, 0, 1023, 255, (short) 1, 0, (short) 1, 0 );
    HSSFSimpleShape shape1 = patriarch.createSimpleShape(a1);
    shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
                    
Text boxes are created using a different call:
HSSFTextbox textbox1 = patriarch.createTextbox(
            new HSSFClientAnchor(0,0,0,0,(short)1,1,(short)2,2));
    textbox1.setString(new HSSFRichTextString("This is a test") );
                    
It's possible to use different fonts to style parts of the text in the textbox. Here's how:
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 );
                    
Just as can be done manually using Excel, it is possible to group shapes together. This is done by calling createGroup() and then creating the shapes using those groups.
It's also possible to create groups within groups.
Warning
Any group you create should contain at least two other shapes or subgroups.
Here's how to create a shape group:
// 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);
                    
If you're being observant you'll noticed that the shapes that are added to the group use a new type of anchor: the HSSFChildAnchor. What happens is that the created group has it's own coordinate space for shapes that are placed into it. POI defaults this to (0,0,1023,255) but you are able to change it as desired. Here's how:
myGroup.setCoordinates(10,10,20,20); // top-left, bottom-right
                    
If you create a group within a group it's also going to have it's own coordinate space.

Styling Shapes

By default shapes can look a little plain. It's possible to apply different styles to the shapes however. The sorts of things that can currently be done are:
  • Change the fill color.
  • Make a shape with no fill color.
  • Change the thickness of the lines.
  • Change the style of the lines. Eg: dashed, dotted.
  • Change the line color.
Here's an examples of how this is done:
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

While the native POI shape drawing commands are the recommended way to draw shapes in a shape it's sometimes desirable to use a standard API for compatibility with external libraries. With this in mind we created some wrappers for Graphics and Graphics2d.
Warning
It's important to not however before continuing that Graphics2d is a poor match to the capabilities of the Microsoft Office drawing commands. The older Graphics class offers a closer match but is still a square peg in a round hole.
All Graphics commands are issued into an HSSFShapeGroup. Here's how it's done:
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 );
                    
The first thing we do is create the group and set it's coordinates to match what we plan to draw. Next we calculate a reasonable fontSizeMultipler then create the EscherGraphics object. Since what we really want is a Graphics2d object we create an EscherGraphics2d object and pass in the graphics object we created. Finally we call a routine that draws into the EscherGraphics2d object.
The vertical points per pixel deserves some more explanation. One of the difficulties in converting Graphics calls into escher drawing calls is that Excel does not have the concept of absolute pixel positions. It measures it's cell widths in 'characters' and the cell heights in points. Unfortunately it's not defined exactly what type of character it's measuring. Presumably this is due to the fact that the Excel will be using different fonts on different platforms or even within the same platform.
Because of this constraint we've had to implement the concept of a verticalPointsPerPixel. This the amount the font should be scaled by when you issue commands such as drawString(). To calculate this value use the follow formula:
multipler = groupHeightInPoints / heightOfGroup
                    
The height of the group is calculated fairly simply by calculating the difference between the y coordinates of the bounding box of the shape. The height of the group can be calculated by using a convenience called HSSFClientAnchor.getAnchorHeightInPoints().
Many of the functions supported by the graphics classes are not complete. Here's some of the functions that are known to work.
  • fillRect()
  • fillOval()
  • drawString()
  • drawOval()
  • drawLine()
  • clearRect()
Functions that are not supported will return and log a message using the POI logging infrastructure (disabled by default).

Outlining

Outlines are great for grouping sections of information together and can be added easily to columns and rows using the POI API. Here's how:
Workbook wb = new HSSFWorkbook();
    Sheet 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();
                    
To collapse (or expand) an outline use the following calls:
sheet1.setRowGroupCollapsed( 7, true );
    sheet1.setColumnGroupCollapsed( (short)4, true );
                    
The row/column you choose should contain an already created group. It can be anywhere within the group.

Images

Images are part of the drawing support. To add an image just call createPicture() on the drawing patriarch. At the time of writing the following types are supported:
  • PNG
  • JPG
  • DIB
It should be noted that any existing drawings may be erased once you add a image to a sheet.
//create a new workbook
    Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook();

    //add picture data to this workbook.
    InputStream is = new FileInputStream("image1.jpeg");
    byte[] bytes = IOUtils.toByteArray(is);
    int pictureIdx = wb.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);
    is.close();

    CreationHelper helper = wb.getCreationHelper();

    //create sheet
    Sheet sheet = wb.createSheet();

    // Create the drawing patriarch.  This is the top level container for all shapes. 
    Drawing drawing = sheet.createDrawingPatriarch();

    //add a picture shape
    ClientAnchor anchor = helper.createClientAnchor();
    //set top-left corner of the picture,
    //subsequent call of Picture#resize() will operate relative to it
    anchor.setCol1(3);
    anchor.setRow1(2);
    Picture pict = drawing.createPicture(anchor, pictureIdx);

    //auto-size picture relative to its top-left corner
    pict.resize();

    //save workbook
    String file = "picture.xls";
    if(wb instanceof XSSFWorkbook) file += "x";
    FileOutputStream fileOut = new FileOutputStream(file);
    wb.write(fileOut);
    fileOut.close();
        
Warning
Picture.resize() works only for JPEG and PNG. Other formats are not yet supported.
Reading images from a workbook:
List lst = workbook.getAllPictures();
    for (Iterator it = lst.iterator(); it.hasNext(); ) {
        PictureData pict = (PictureData)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();
        }
    }
      

Named Ranges and Named Cells

Named Range is a way to refer to a group of cells by a name. Named Cell is a degenerate case of Named Range in that the 'group of cells' contains exactly one cell. You can create as well as refer to cells in a workbook by their named range. When working with Named Ranges, the classes: org.apache.poi.hssf.util.CellReference and & org.apache.poi.hssf.util.AreaReference are used (these work for both XSSF and HSSF, despite the package name).
Creating Named Range / Named Cell
// setup code
    String sname = "TestSheet", cname = "TestName", cvalue = "TestVal";
    Workbook wb = new HSSFWorkbook();
    Sheet sheet = wb.createSheet(sname);
    sheet.createRow(0).createCell((short) 0).setCellValue(cvalue);

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

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

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

    // 4. create named formula
    Name namedCel4 = wb.createName();
    namedCel4.setNameName("my_sum");
    namedCel4.setRefersToFormula("SUM(sname+!$I$2:$I$6)");
            
Reading from Named Range / Named Cell
// setup code
    String cname = "TestName";
    Workbook wb = getMyWorkbook(); // retrieve workbook

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

    // retrieve the cell at the named range and test its contents
    AreaReference aref = new AreaReference(aNamedCell.getRefersToFormula());
    CellReference[] crefs = aref.getAllReferencedCells();
    for (int i=0; i
        Sheet s = wb.getSheet(crefs[i].getSheetName());
        Row r = sheet.getRow(crefs[i].getRow());
        Cell c = r.getCell(crefs[i].getCol());
        // extract the cell contents based on cell type etc.
    }
            
Reading from non-contiguous Named Ranges
// Setup code
    String cname = "TestName";
    Workbook wb = getMyWorkbook(); // retrieve workbook

    // Retrieve the named range
    // Will be something like "$C$10,$D$12:$D$14";
    int namedCellIdx = wb.getNameIndex(cellName);
    Name aNamedCell = wb.getNameAt(namedCellIdx);

    // Retrieve the cell at the named range and test its contents
    // Will get back one AreaReference for C10, and
    //  another for D12 to D14
    AreaReference[] arefs = AreaReference.generateContiguous(aNamedCell.getRefersToFormula());
    for (int i=0; i
        // Only get the corners of the Area
        // (use arefs[i].getAllReferencedCells() to get all cells)
        CellReference[] crefs = arefs[i].getCells();
        for (int j=0; j
            // Check it turns into real stuff
            Sheet s = wb.getSheet(crefs[j].getSheetName());
            Row r = s.getRow(crefs[j].getRow());
            Cell c = r.getCell(crefs[j].getCol());
            // Do something with this corner cell
        }
    }
            
Note, when a cell is deleted, Excel does not delete the attached named range. As result, workbook can contain named ranges that point to cells that no longer exist. You should check the validity of a reference before constructing AreaReference
if(name.isDeleted()){
      //named range points to a deleted cell. 
    } else {
      AreaReference ref = new AreaReference(name.getRefersToFormula());
    }
            

Cell Comments - HSSF and XSSF (slight differences though)

In HSSF Excel, cell comments were added to the file format as a bit of a cludge. As such, comments are a kind of a text shape, so inserting a comment is very similar to placing a text box in a worksheet.
In XSSF Excel, cell comments are more cleanly done. Each Sheet has a list of its comments, and they can be added much like other cell properties.
Once you have created your comment, how you use it is very similar between HSSF and XSSF. It is only the creation of a new comment where things differ.
For HSSF, the process is:
HSSFWorkbook wb = new HSSFWorkbook();
    HSSFSheet sheet = wb.createSheet("Cell comments in POI HSSF");
    CreationHelper createHelper = wb.getCreationHelper();

    // 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
    Cell cell1 = sheet.createRow(3).createCell((short)1);
    cell1.setCellValue(new HSSFRichTextString("Hello, World"));

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

     // set text in the comment
    comment1.setString(createHelper.createRichTextString("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 Cell.setCellComment method
    cell1.setCellComment(comment1);


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

    // And a comment for it
    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 comment is visible.
     */
    comment2.setRow(6);
    comment2.setColumn((short)1);

    FileOutputStream out = new FileOutputStream("poi_comment.xls");
    wb.write(out);
    out.close();
        
For XSSF, the simpler process is:
XSSFWorkbook wb = new XSSFWorkbook();
    XSSFSheet sheet = wb.createSheet("Cell comments in POI XSSF");
    CreationHelper createHelper = wb.getCreationHelper();

    // Create a cell in row 3
    Cell cell1 = sheet.createRow(3).createCell((short)1);
    cell1.setCellValue(new XSSFRichTextString("Hello, World"));

    // Create a comment, and set the text and author
    // (You can see the author in the status bar when moving mouse
    //  over the commented cell)
    Comment comment1 = sheet.createComment();
    comment1.setString(createHelper.createRichTextString("We can set comments in POI"));
    comment1.setAuthor("Apache Software Foundation");


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


 // The other way is to set the row and column
    // This could point to a cell that isn't defined, and the comment will
    //  will still show up all the same
    Comment comment2 = sheet.createComment();
    comment2.setString(createHelper.createRichTextString("Comment for missing cell"));
    comment2.setAuthor("Apache POI");
    comment2.setRow(11);
    comment2.setColumn(1);

    // Write out
    FileOutputStream out = new FileOutputStream("poi_comment.xls");
    wb.write(out);
    out.close();
        
Reading cell comments
Cell cell = sheet.get(3).getColumn((short)1);
    Comment comment = cell.getCellComment();
    if (comment != null) {
      RichTextString str = comment.getString();
      String author = comment.getAuthor();
    }
    //  alternatively you can retrieve cell comments by (row, column)
    comment = sheet.getCellComment(3, 1);
  

Adjust column width to fit the contents

Sheet sheet = workbook.getSheetAt(0);
    sheet.autoSizeColumn((short)0); //adjust width of the first column
    sheet.autoSizeColumn((short)1); //adjust width of the second column
        
Warning
To calculate column width HSSFSheet.autoSizeColumn uses Java2D classes that throw exception if graphical environment is not available. In case if graphical environment is not available, you must tell Java that you are running in headless mode and set the following system property: java.awt.headless=true .

How to read hyperlinks

Sheet sheet = workbook.getSheetAt(0);

    Cell cell = sheet.getRow(0).getCell((short)0);
    Hyperlink link = cell.getHyperlink();
    if(link != null){
        System.out.println(link.getAddress());
    }
      

How to create hyperlinks

Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook();
    CreationHelper createHelper = wb.getCreationHelper();

    //cell style for hyperlinks
    //by default hypelrinks are blue and underlined
    CellStyle hlink_style = wb.createCellStyle();
    Font hlink_font = wb.createFont();
    hlink_font.setUnderline(Font.U_SINGLE);
    hlink_font.setColor(IndexedColors.BLUE.getIndex());
    hlink_style.setFont(hlink_font);

    Cell cell;
    Sheet sheet = wb.createSheet("Hyperlinks");
    //URL
    cell = sheet.createRow(0).createCell((short)0);
    cell.setCellValue("URL Link");

    Hyperlink link = createHelper.createHyperlink(Hyperlink.LINK_URL);
    link.setAddress("http://poi.apache.org/");
    cell.setHyperlink(link);
    cell.setCellStyle(hlink_style);

    //link to a file in the current directory
    cell = sheet.createRow(1).createCell((short)0);
    cell.setCellValue("File Link");
    link = createHelper.createHyperlink(Hyperlink.LINK_FILE);
    link.setAddress("link1.xls");
    cell.setHyperlink(link);
    cell.setCellStyle(hlink_style);

    //e-mail link
    cell = sheet.createRow(2).createCell((short)0);
    cell.setCellValue("Email Link");
    link = createHelper.createHyperlink(Hyperlink.LINK_EMAIL);
    //note, if subject contains white spaces, make sure they are url-encoded
    link.setAddress("mailto:poi@apache.org?subject=Hyperlinks");
    cell.setHyperlink(link);
    cell.setCellStyle(hlink_style);

    //link to a place in this workbook

    //create a target sheet and cell
    Sheet sheet2 = wb.createSheet("Target Sheet");
    sheet2.createRow(0).createCell((short)0).setCellValue("Target Cell");

    cell = sheet.createRow(3).createCell((short)0);
    cell.setCellValue("Worksheet Link");
    Hyperlink link2 = createHelper.createHyperlink(Hyperlink.LINK_DOCUMENT);
    link2.setAddress("'Target Sheet'!A1");
    cell.setHyperlink(link2);
    cell.setCellStyle(hlink_style);

    FileOutputStream out = new FileOutputStream("hyperinks.xlsx");
    wb.write(out);
    out.close();