diff --git a/Applications/FileIO/CsvInterface.cpp b/Applications/FileIO/CsvInterface.cpp
index ce2878960cf3a51b5ce117d150be8905acfd5bad..9d75c49cba0dd434b7c1076c588d79de68b04b26 100644
--- a/Applications/FileIO/CsvInterface.cpp
+++ b/Applications/FileIO/CsvInterface.cpp
@@ -14,12 +14,20 @@
 #include "CsvInterface.h"
 
 #include <algorithm>
+#include <iostream>
+#include <numeric>
 #include <stdexcept>
 
 #include "GeoLib/Point.h"
 
 namespace FileIO {
 
+CsvInterface::CsvInterface()
+: _writeCsvHeader(true)
+{
+}
+
+
 int CsvInterface::readPoints(std::string const& fname, char delim,
                              std::vector<GeoLib::Point*> &points)
 {
@@ -181,4 +189,64 @@ std::size_t CsvInterface::findColumn(std::string const& line, char delim, std::s
     return count;
 }
 
+void CsvInterface::addIndexVectorForWriting(std::size_t s)
+{
+    std::vector<int> idx_vec(s);
+    std::iota(idx_vec.begin(), idx_vec.end(), 0);
+    addVectorForWriting("Index", idx_vec);
+}
+
+bool CsvInterface::write()
+{
+    if (_data.empty())
+    {
+        ERR ("CsvInterface::write() - No data to write.");
+        return false;
+    }
+
+    std::size_t const n_vecs (_data.size());
+    std::size_t const vec_size (getVectorSize(0));
+
+    if (_writeCsvHeader)
+    {
+        _out << _vec_names[0];
+        for (std::size_t i=1; i<n_vecs; ++i)
+            _out << "\t" << _vec_names[i];
+        _out << "\n";
+    }
+
+    for (std::size_t j=0; j<vec_size; ++j)
+    {
+        writeValue(0,j);
+        for (std::size_t i=1; i<n_vecs; ++i)
+        {
+            _out << "\t";
+            writeValue(i,j);
+        }
+        _out << "\n";
+    }
+    return true;
+}
+
+std::size_t CsvInterface::getVectorSize(std::size_t idx) const
+{
+    if (_data[idx].type() == typeid(std::vector<std::string>))
+        return boost::any_cast<std::vector<std::string>>(_data[idx]).size();
+    else if (_data[idx].type() == typeid(std::vector<double>))
+        return boost::any_cast<std::vector<double>>(_data[idx]).size();
+    else if (_data[idx].type() == typeid(std::vector<int>))
+        return boost::any_cast<std::vector<int>>(_data[idx]).size();
+    return 0;
+}
+
+void CsvInterface::writeValue(std::size_t vec_idx, std::size_t in_vec_idx)
+{
+    if (_data[vec_idx].type() == typeid(std::vector<std::string>))
+        _out << boost::any_cast<std::vector<std::string>>(_data[vec_idx])[in_vec_idx];
+    else if (_data[vec_idx].type() == typeid(std::vector<double>))
+        _out << boost::any_cast<std::vector<double>>(_data[vec_idx])[in_vec_idx];
+    else if (_data[vec_idx].type() == typeid(std::vector<int>))
+        _out << boost::any_cast<std::vector<int>>(_data[vec_idx])[in_vec_idx];
+}
+
 } // end namespace FileIO
diff --git a/Applications/FileIO/CsvInterface.h b/Applications/FileIO/CsvInterface.h
index e78597c96e5eb72235f4e02fb1fe883096c19601..cf157b73cb73f664a62bb5416820b6188c22b4ea 100644
--- a/Applications/FileIO/CsvInterface.h
+++ b/Applications/FileIO/CsvInterface.h
@@ -15,6 +15,7 @@
 #define CSVINTERFACE_H_
 
 #include <logog/include/logog.hpp>
+#include <boost/any.hpp>
 
 #include <array>
 #include <fstream>
@@ -22,10 +23,12 @@
 #include <limits>
 #include <list>
 #include <string>
+#include <typeinfo>
 #include <vector>
 
 
 #include "BaseLib/StringTools.h"
+#include "BaseLib/IO/Writer.h"
 
 namespace GeoLib {
     class Point;
@@ -36,9 +39,50 @@ namespace FileIO {
 /**
  * Interface for reading CSV file formats.
  */
-class CsvInterface {
+class CsvInterface  : public BaseLib::IO::Writer
+{
 
 public:
+    /// Contructor (only needed for writing files)
+    CsvInterface();
+
+    /// Returns the number of vectors currently staged for writing.
+    std::size_t getNArrays() const { return _vec_names.size(); }
+
+    /// Adds an index vector of size s to the CSV file
+    void addIndexVectorForWriting(std::size_t s);
+
+    /// Stores if the CSV file to be written should include a header or not.
+    void setCsvHeader(bool write_header) { _writeCsvHeader = write_header; }
+
+    /// Adds a data vector to the CSV file. All data vectors have to have the same size.
+    /// Vectors will be written in the same sequence they have been added to the interface.
+    template<typename T>
+    bool addVectorForWriting(std::string const& vec_name, std::vector<T> const& vec)
+    {
+        static_assert(std::is_same<T, std::string>::value
+                || std::is_same<T, double>::value
+                || std::is_same<T, int>::value,
+                "CsvInterface can only write vectors of strings, doubles or ints.");
+
+        if (!_data.empty())
+        {
+            std::size_t const vec_size (getVectorSize(0));
+            if (vec_size != vec.size())
+            {
+                ERR ("Vector size does not match existing data (should be %d).", vec_size);
+                return false;
+            }
+        }
+
+        _vec_names.push_back(vec_name);
+        _data.push_back(vec);
+        return true;
+    }
+
+    /// Writes the CSV file.
+    bool write();
+
     /**
      * Reads 3D points from a CSV file. It is assumed that the file has a header
      * specifying a name for each of the columns. The first three columns will be
@@ -178,6 +222,20 @@ private:
 
     /// Returns the number of the column with column_name (or std::numeric_limits::max() if no such column has been found).
     static std::size_t findColumn(std::string const& line, char delim, std::string const& column_name);
+
+    /// Returns the size of the vector with the given index
+    std::size_t getVectorSize(std::size_t idx) const;
+
+    /**
+     * Writes a value from a vector to the file.
+     * \param vec_idx     Index of the vector
+     * \param in_vec_idx  Entry in the selected vector
+     */
+    void writeValue(std::size_t vec_idx, std::size_t in_vec_idx);
+
+    bool _writeCsvHeader;
+    std::vector<std::string> _vec_names;
+    std::vector< boost::any > _data;
 };
 
 } // FileIO
diff --git a/Tests/FileIO/TestCsvWriter.cpp b/Tests/FileIO/TestCsvWriter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8db81e3796e132167b6fe56171c7c8ff0a0d3325
--- /dev/null
+++ b/Tests/FileIO/TestCsvWriter.cpp
@@ -0,0 +1,81 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ *
+ */
+
+#include <cstdio>
+
+#include "gtest/gtest.h"
+
+#include <string>
+#include <vector>
+
+#include "BaseLib/BuildInfo.h"
+#include "Applications/FileIO/CsvInterface.h"
+
+TEST(CsvWriter, WriteReadTest)
+{
+    std::string test_file(BaseLib::BuildInfo::tests_tmp_path + "TestData.csv");
+
+    std::vector<std::string> str_vec {"Red", "Orange", "Yellow", "Green", "Blue", "Indigo", "Violet" };
+    std::vector<int> int_vec { 1, 2, 4, 8, 16, 32, 64 };
+    std::vector<double> dbl_vec;
+    std::srand ( static_cast<unsigned>(std::time(nullptr)) );
+    for (std::size_t i=0; i<int_vec.size(); ++i)
+        dbl_vec.push_back(static_cast<double>(std::rand()) / RAND_MAX);
+
+    FileIO::CsvInterface csv;
+    bool added;
+    std::vector<std::string> vec_names { "String Vector", "Int Vector", "Double Vector"};
+    added = csv.addVectorForWriting(vec_names[0], str_vec);
+    ASSERT_EQ(true, added);
+    added = csv.addVectorForWriting(vec_names[1], int_vec);
+    ASSERT_EQ(true, added);
+    added = csv.addVectorForWriting(vec_names[2], dbl_vec);
+    ASSERT_EQ(true, added);
+    int_vec.push_back(128);
+    added = csv.addVectorForWriting(vec_names[1], int_vec);
+    ASSERT_EQ(false, added);
+    ASSERT_EQ(3, csv.getNArrays());
+    csv.addIndexVectorForWriting(str_vec.size());
+    ASSERT_EQ(4, csv.getNArrays());
+    int result = csv.writeToFile(test_file);
+    ASSERT_EQ(1, result);
+
+    std::vector<std::string> str_result;
+    result = FileIO::CsvInterface::readColumn<std::string>(test_file, '\t', str_result, vec_names[0]);
+    ASSERT_EQ(0, result);
+    ASSERT_EQ(str_vec.size(), str_result.size());
+
+    std::vector<int> idx_result;
+    result = FileIO::CsvInterface::readColumn<int>(test_file, '\t', idx_result, "Index");
+    ASSERT_EQ(0, result);
+    ASSERT_EQ(dbl_vec.size(), idx_result.size());
+
+    std::vector<int> int_result;
+    result = FileIO::CsvInterface::readColumn<int>(test_file, '\t', int_result, vec_names[1]);
+    ASSERT_EQ(0, result);
+    // testing for vector length -1 because it had increased previously when testing size requirements
+    ASSERT_EQ(int_vec.size()-1, int_result.size());
+
+    std::vector<double> dbl_result;
+    result = FileIO::CsvInterface::readColumn<double>(test_file, '\t', dbl_result, vec_names[2]);
+    ASSERT_EQ(0, result);
+    ASSERT_EQ(dbl_vec.size(), dbl_result.size());
+
+    for (std::size_t i=0; i<str_vec.size(); ++i)
+    {
+        ASSERT_EQ(str_vec[i], str_result[i]);
+        ASSERT_EQ(int_vec[i], int_result[i]);
+        ASSERT_NEAR(dbl_vec[i], dbl_result[i], 10 * std::numeric_limits<double>::epsilon());
+        ASSERT_EQ(static_cast<int>(i), idx_result[i]);
+    }
+
+    std::remove(test_file.c_str());
+}
+