views:

372

answers:

2

I have a hashMap in java in terms of some keys which each key is indicating a flow. Then each value showing statics about each packet belongs to that flow.

What I need to do is, to draw graphs for each flow based on those values. for example:

  Flow1: {[length, time],[],[],...}
  Flow2: {[length, time],[length, time],[],...}

i need to create a CSV file that then can be read from MS excel. Can anyone has the idea to give me some clues please?

Edited: here is my hashMap:

    Iterator<Flows> iterator =  myHashMap.keySet().iterator();
    String fileName = ((args.length > 0) ? args[0] : "jexcel.xls");
    Map<String, ArrayList> csv = new HashMap<String, ArrayList>();
    int i=0;

    while(iterator.hasNext()){
        Flows key = iterator.next();
        ArrayList value = myHashMap.get(key);
        csv.put("Flow["+i+"]", value);


    }
+2  A: 

You can use from following API's.

POI : http://poi.apache.org

javacsv : http://sourceforge.net/projects/javacsv

JExcel : http://jexcelapi.sourceforge.net/

opencsv : http://opencsv.sourceforge.net/

Following is writting to csv example using supercsv api:

import java.io.FileWriter;
import java.util.HashMap;
import org.supercsv.io.*;
import org.supercsv.prefs.CsvPreference;

public class CSVWriteExample {

    /**
     * @param args
     */
    public static void main(String[] args) throws Exception{  

      ICsvMapWriter writer = new CsvMapWriter(new FileWriter("person.csv"), CsvPreference.EXCEL_PREFERENCE);  
      try {  
        final String[] header = new String[] { "name", "city", "pin" };  
        // set up some data to write  
        final HashMap<string, ?="" super="" object=""> data1 = new HashMap<string, object="">();  
        data1.put(header[0], "Raj");  
        data1.put(header[1], "Vijayawada");  
        data1.put(header[2], 500026);  
        final HashMap<string, ?="" super="" object=""> data2 = new HashMap<string, object="">();  
        data2.put(header[0], "Suneel");  
        data2.put(header[1], "Tenali");  
        data2.put(header[2], 522202);  

        // the actual writing  
        writer.writeHeader(header);  
        writer.write(data1, header);  
        writer.write(data2, header);  

        System.out.println("Writing Completed...!");  
      } finally {  
        writer.close();  
      }  
 }
}

Also realted questions on stackoverflow can be found :

http://stackoverflow.com/questions/200609/can-you-recommend-a-java-library-for-reading-and-possibly-writing-csv-files

http://stackoverflow.com/questions/101100/csv-api-for-java

YoK
@Yok. thanks. im so confused, reading the links you suggested. i will look at the code you provided now.
Red Lion
@Red Lion Ya there are too many options for writing to CSV. For simple cases like yours , you could actually use any of these without any problems :).
YoK
@Yok: can you please look at my code, i edited my post.
Red Lion
@Red Lion Your code doesn't look correct. I wont be able to do it myself from here. Checkout supercsv examples http://supercsv.sourceforge.net/codeExamples_general.html http://supercsv.sourceforge.net/codeExamples_partial_reading_writing.html
YoK
+2  A: 

If you really want an Excel file, the best library for creating one is Andy Khan's JExcel.

I think you'd need one worksheet per flow, with .csv pairs for each one, sorted by time.

If these are graphs of a variable versus time, wouldn't "time" be the first value in each pair?

Here's how I'd do it. It works perfectly for the simple test case I supplied - it's working code that you'll be able to extend.

package jexcel;

import jxl.Workbook;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JExcelUtils
{
    public static void main(String[] args)
    {
        String fileName = ((args.length > 0) ? args[0] : "jexcel.xls");
        Map<String, List<Pair>> csv = new HashMap<String, List<Pair>>()
        {{
            put("Flow1", fromArrayToList(new double[][]
            {
                { 0.0, 0.0 },
                { 0.1, 1.0 },
                { 0.2, 2.0 },
                { 0.3, 3.0 },
                { 0.4, 4.0 },
                { 0.5, 5.0 },    
            }));
            put("Flow2", fromArrayToList(new double[][]
            {
                { 0.0, 0.0 },
                { 0.1, 1.0 },
                { 0.2, 4.0 },
                { 0.3, 9.0 },
                { 0.4, 16.0 },
                { 0.5, 25.0 },
            }));
        }};
        WritableWorkbook excelContents = null;

        try
        {
            File excelFile = new File(fileName);
            excelContents = createExcel(excelFile, csv);
            excelContents.write();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        catch (WriteException e)
        {
            e.printStackTrace();
        }
        finally
        {
            try { if (excelContents != null) excelContents.close(); } catch (Exception e) { e.printStackTrace(); }
        }
    }


    public static List<Pair> fromArrayToList(double [][] input)
    {
        List<Pair> result = new ArrayList<Pair>();

        for (int i = 0; i < input.length; ++i)
        {
            result.add(new Pair(input[i][0], input[i][1]));            
        }

        return result;
    }

    public static WritableWorkbook createExcel(File excelFile, Map<String, List<Pair>> worksheets) throws IOException, WriteException
    {
        WritableWorkbook result = Workbook.createWorkbook(excelFile);

        int order = 0;
        for (String worksheetName : worksheets.keySet())
        {
            WritableSheet worksheet = result.createSheet(worksheetName, order++);
            List<Pair> worksheetValues = worksheets.get(worksheetName);
            for (int row = 0; row < worksheetValues.size(); ++row)
            {
                worksheet.addCell(new jxl.write.Number(0, row, worksheetValues.get(row).getX()));
                worksheet.addCell(new jxl.write.Number(1, row, worksheetValues.get(row).getY()));
            }
        }

        return result;
    }

}


class Pair
{
    private double x;
    private double y;

    Pair(double x, double y)
    {
        this.x = x;
        this.y = y;
    }

    public double getX()
    {
        return x;
    }

    public double getY()
    {
        return y;
    }
}
duffymo
yes, exactly. i need one sheet per each flow. i can change the ordering it s not difficult at all.
Red Lion
first of all thank you very much.secondly how can i see this program's output in excel?
Red Lion
@ duffymo: my values are an arrayList and by this map my values should be double[][].
Red Lion
@RedLion - open the "jexcel.xls" file that it creates as its default OR enter a path to the file of your choosing on the command line. You should be able to change the data structure that holds your values to whatever you wish. I can do it for you if you need a hand.
duffymo
@RedLion: Please see revised code.
duffymo
@RedLion: If your values are streamed together in a List<Double> instead of using the Pair helper class, you'll just change the code to step through and make the odd values the "x" and even values the "y". Should be easy to do.
duffymo
@Duffy: thanks for all the helps. i really appreciate that.my values are an arrayList of an object FlowStatics flowStatics = new FlowStatics(packetLength,timeArrival); staticsArray.add(flowStatics); and also you are adding the values manually, my values are big and it is impossible to do this way.finally i didnt get how you said i can't see this jexcel.xls, you have not specify any path.Sorry i know im asking too much, but i really need it.
Red Lion
@RedLion - You'll have to take my code, compile, and run it to see the output file. It'll prove to you that the code works as written, and lets you see what it produces. If you haven't done that yet, try it now. I'm sorry, but you're on your own adapting it to your own data structure. I think I've already done quite a lot, don't you?
duffymo
@RedLion: Accept my answer. It'll boost your meager acceptance rate.
duffymo
@duffymo: i appreciate ur help. i copied and paste ur exact code just to see how does it work, thats why i asked how to see the result. i didnt doubt it wont work!
Red Lion
Your doubt doesn't concern me; I know it works because I ran it myself. I get the jexcel.xls file in my project root. Do you not see it?
duffymo