Package org.apache.wicket.extensions.markup.html.repeater.data.table.export

Source Code of org.apache.wicket.extensions.markup.html.repeater.data.table.export.CSVDataExporter

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.wicket.extensions.markup.html.repeater.data.table.export;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.List;
import org.apache.wicket.Application;
import org.apache.wicket.Session;
import org.apache.wicket.markup.repeater.data.IDataProvider;
import org.apache.wicket.model.Model;
import org.apache.wicket.util.convert.IConverter;
import org.apache.wicket.util.lang.Args;

/**
* An {@link IDataExporter} that exports data to a CSV file. This class allows for customization of the exact CSV format, including
* setting the delimiter, the text quoting character and the character set.
* <p>
* This class will export CSV files in a format consistent with RFC4180 by default.
*
* @author Jesse Long
*/
public class CSVDataExporter extends AbstractDataExporter
{
  private char delimiter = ',';

  private String characterSet = "utf-8";

  private char quoteCharacter = '"';

  private boolean exportHeadersEnabled = true;

  /**
   * Creates a new instance.
   */
  public CSVDataExporter()
  {
    super(Model.of("CSV"), "text/csv", "csv");
  }

  /**
   * Sets the delimiter to be used to separate fields. The default delimiter is a colon.
   *
   * @param delimiter
   *      The delimiter to be used to separate fields.
   * @return {@code this}, for chaining.
   */
  public CSVDataExporter setDelimiter(char delimiter)
  {
    this.delimiter = delimiter;
    return this;
  }

  /**
   * Returns the delimiter to be used for separating fields.
   *
   * @return the delimiter to be used for separating fields.
   */
  public char getDelimiter()
  {
    return delimiter;
  }

  /**
   * Returns the character set encoding to be used when exporting data.
   *
   * @return the character set encoding to be used when exporting data.
   */
  public String getCharacterSet()
  {
    return characterSet;
  }

  /**
   * Sets the character set encoding to be used when exporting data. This defaults to UTF-8.
   *
   * @param characterSet
   *      The character set encoding to be used when exporting data.
   * @return {@code this}, for chaining.
   */
  public CSVDataExporter setCharacterSet(String characterSet)
  {
    this.characterSet = Args.notNull(characterSet, "characterSer");
    return this;
  }

  /**
   * Returns the character to be used for quoting fields.
   *
   * @return the character to be used for quoting fields.
   */
  public char getQuoteCharacter()
  {
    return quoteCharacter;
  }

  /**
   * Sets the character to be used to quote fields. This defaults to double quotes,
   *
   * @param quoteCharacter
   *      The character to be used to quote fields.
   * @return {@code this}, for chaining.
   */
  public CSVDataExporter setQuoteCharacter(char quoteCharacter)
  {
    this.quoteCharacter = quoteCharacter;
    return this;
  }

  /**
   * Returns the content type of the exported data. For CSV, this is normally
   * "text/csv". This methods adds the character set and header values, in accordance with
   * RFC4180.
   *
   * @return  the content type of the exported data.
   */
  @Override
  public String getContentType()
  {
    return super.getContentType() + "; charset=" + characterSet + "; header=" + ((exportHeadersEnabled) ? "present" : "absent");
  }

  /**
   * Turns on or off export headers functionality. If this is set to {@code true}, then the first
   * line of the export will contain the column headers. This defaults to {@code true}.
   *
   * @param exportHeadersEnabled
   *      A boolean indicating whether or not headers should be exported.
   * @return {@code this}, for chaining.
   */
  public CSVDataExporter setExportHeadersEnabled(boolean exportHeadersEnabled)
  {
    this.exportHeadersEnabled = exportHeadersEnabled;
    return this;
  }

  /**
   * Indicates if header exporting is enabled. Defaults to {@code true}.
   *
   * @return a boolean indicating if header exporting is enabled.
   */
  public boolean isExportHeadersEnabled()
  {
    return exportHeadersEnabled;
  }

  /**
   * Quotes a value for export to CSV. According to RFC4180, this should just duplicate all occurrences
   * of the quote character and wrap the result in the quote character.
   *
   * @param value
   *      The value to be quoted.
   * @return a quoted copy of the value.
   */
  protected String quoteValue(String value)
  {
    return quoteCharacter + value.replace("" + quoteCharacter, "" + quoteCharacter + quoteCharacter) + quoteCharacter;
  }

  @Override
  public <T> void exportData(IDataProvider<T> dataProvider, List<IExportableColumn<T, ?>> columns, OutputStream outputStream)
    throws IOException
  {
    PrintWriter out = new PrintWriter(new OutputStreamWriter(outputStream, Charset.forName(characterSet)));
    try
    {
      if (isExportHeadersEnabled())
      {
        boolean first = true;
        for (IExportableColumn<T, ?> col : columns)
        {
          if (first)
          {
            first = false;
          }
          else
          {
            out.print(delimiter);
          }
          out.print(quoteValue(col.getDisplayModel().getObject()));
        }
        out.print("\r\n");
      }
      long numberOfRows = dataProvider.size();
      Iterator<? extends T> rowIterator = dataProvider.iterator(0, numberOfRows);
      while (rowIterator.hasNext())
      {
        T row = rowIterator.next();

        boolean first = true;
        for (IExportableColumn<T, ?> col : columns)
        {
          if (first)
          {
            first = false;
          }
          else
          {
            out.print(delimiter);
          }

          Object o = col.getDataModel(dataProvider.model(row)).getObject();

          if (o != null)
          {
            Class<?> c = o.getClass();

            String s;

            IConverter converter = Application.get().getConverterLocator().getConverter(c);

            if (converter == null)
            {
              s = o.toString();
            }
            else
            {
              s = converter.convertToString(o, Session.get().getLocale());
            }

            out.print(quoteValue(s));
          }
        }
        out.print("\r\n");
      }
    }
    finally
    {
      out.close();
    }
  }
}
TOP

Related Classes of org.apache.wicket.extensions.markup.html.repeater.data.table.export.CSVDataExporter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.