How do I upload a CSV file and then automatically insert the data into the DB?

texasdude11 picture texasdude11 · Jan 1, 2013 · Viewed 8.4k times · Source

I have Java based Spring MVC application that also uses Spring security. I am using hibernate as an ORM tool for this web app.

Following is my requirement --

User will have ability to upload a CSV file using a web browser. The format of the CSV file is known to have following 5 fields:

userId, location, itemId, quantity, tranDate
001, NY, 00A8D5, 2, 12/31/2012
002, MN, 00A7C1, 10, 12/22/2012
.
.

like this there are about 100 rows.

I am using Super CSV in the project:

private void readWithCsvBeanReader(String CSV_FILENAME) throws Exception {

    String CSV_FILENAME = "\\\\Serv01\\Files\\QueryResult.csv";
    //String CSV_FILENAME = "C:\\Files\\QueryResult.csv";
    ICsvBeanReader beanReader = null;
    try {
        beanReader = new CsvBeanReader(new FileReader(CSV_FILENAME),
                CsvPreference.STANDARD_PREFERENCE);

        // the header elements are used to map the values to the bean (names
        // must match)
        final String[] header = beanReader.getHeader(true);
        // get Cell Processor
        final CellProcessor[] processors = getProcessors();

Here I am reading the contents of the CSV file and then using Hibernate, I am inserting it.

This works fine as I am providing the CSV path locally or on the windows share.

String CSV_FILENAME = "\\\\Serv01\\Files\\QueryResult.csv";
or via this:
String CSV_FILENAME = "C:\\Files\\QueryResult.csv"; 
  1. How can I achieve this requirement such that the CSV file path location will be provided by a button on the webpage using Spring MVC?

  2. Is it also possible to pick up the file automatically from a remote location such that I will upload the file in a FTP location and then the program can connect to the remote ftp location and process the file on a schedule?

PS: I am new to file operations and if someone can point towards some article then it will be great.

Answer

Adam Gent picture Adam Gent · Jan 1, 2013

like this there are about 100 rows.

Don't bother saving the CSV as a tmp file as Spring's Mulitpart will do that for you and just insert the rows directly (the request may take longer to process but given your ostensible current knowledge you can worry about optimizing that later)

private void readWithCsvBeanReader(MultipartFile uploadedFile) throws Exception {

    ICsvBeanReader beanReader = null;
    try {
        beanReader = new CsvBeanReader(new InputStreamReader(uploadedFile.getInputStream()),
                CsvPreference.STANDARD_PREFERENCE);

        // the header elements are used to map the values to the bean (names
        // must match)
        final String[] header = beanReader.getHeader(true);
        // get Cell Processor
        final CellProcessor[] processors = getProcessors();

Make your controller something like:

@RequestMapping(value = "/add", method=RequestMethod.POST)
public String upload(@RequestParam("file") MultipartFile file) throws IOException {
// call your csv parsing code.
}

Make sure you make your FORM looks something like:

<h1>Add a File for testing</h1>
<form method="post" action="/add" class="well form-vertical" enctype="multipart/form-data">
    <input type="file" name="file" />
    <button type="submit" class="btn">{{actionLabel}}</button>
</form>

Take notice of the enctype

For input and output you should understand Java's IO Decorator pattern.

I Recommend you keep it as simple as possible so that you can learn the basics. Then worry about adding more robust solutions/libraries.