How to create a CSV file using Swift
Step 1:
Create an array, named as "employeeArray" which will store all our records for the employees as key value objects. Also we will add dummy data to the newly created array
class ViewController: UIViewController {
var employeeArray:[Dictionary<String, AnyObject>] = Array()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
for i in 1...10 {
var dct = Dictionary<String, AnyObject>()
dct.updateValue(i as AnyObject, forKey: "EmpID")
dct.updateValue("NameForEmplyee id = \(i)" as AnyObject, forKey: "EmpName")
employeeArray.append(dct)
}
}
}
Step 2: Now we have data with us, and its time to create CSV(comma separated values) file using swift programmatically. For this we will loop through our records in "employeeArray" and append them in a string. Then we will write this string to our document directory of the app. All the stuff goes in different function named as "createCSV", below is the code for the same
func createCSV(from recArray:[Dictionary<String, AnyObject>]) {
var csvString = "\("Employee ID"),\("Employee Name")\n\n"
for dct in recArray {
csvString = csvString.appending("\(String(describing: dct["EmpID"]!)) ,\(String(describing: dct["EmpName"]!))\n")
}
let fileManager = FileManager.default
do {
let path = try fileManager.url(for: .documentDirectory, in: .allDomainsMask, appropriateFor: nil, create: false)
let fileURL = path.appendingPathComponent("CSVRec.csv")
try csvString.write(to: fileURL, atomically: true, encoding: .utf8)
} catch {
print("error creating file")
}
}
Step 3: Finally we will call our function from "viewDidLoad". Below is the complete code
class ViewController: UIViewController {
var employeeArray:[Dictionary<String, AnyObject>] = Array()
override func viewDidLoad() {
super.viewDidLoad()
for i in 1...10 {
var dct = Dictionary<String, AnyObject>()
dct.updateValue(i as AnyObject, forKey: "EmpID")
dct.updateValue("NameForEmplyee id = \(i)" as AnyObject, forKey: "EmpName")
employeeArray.append(dct)
}
createCSV(from: employeeArray)
}
func createCSV(from recArray:[Dictionary<String, AnyObject>]) {
var csvString = "\("Employee ID"),\("Employee Name")\n\n"
for dct in recArray {
csvString = csvString.appending("\(String(describing: dct["EmpID"]!)) ,\(String(describing: dct["EmpName"]!))\n")
}
let fileManager = FileManager.default
do {
let path = try fileManager.url(for: .documentDirectory, in: .allDomainsMask, appropriateFor: nil, create: false)
let fileURL = path.appendingPathComponent("CSVRec.csv")
try csvString.write(to: fileURL, atomically: true, encoding: .utf8)
} catch {
print("error creating file")
}
}
}
Fëanor Tang
Updated on June 07, 2022Comments
-
Fëanor Tang over 1 year
In an app I created to collect data from
Apple
pencil input, I tried to export the data into a CSV file. But so far, I only managed to create a single column which records the time length. I want to add another column to record the force from theApple
pencil.This is what I have tried to do:
var patientsData:[Dictionary<String, AnyObject>] = Array() var dct = Dictionary<String, AnyObject>() // MARK: CSV writing func createCSVX(from recArray:[Dictionary<String, AnyObject>]) { var csvString = "\("Time")\n" dct.updateValue(TestDraw.time as AnyObject, forKey: "T") csvString = csvString.appending("\(String(describing: dct["T"]))\n") patientsData.append(dct) let fileManager = FileManager.default do { let path = try fileManager.url(for: .documentDirectory, in: .allDomainsMask, appropriateFor: nil, create: false) let fileURL = path.appendingPathComponent("TrailTime.csv") try csvString.write(to: fileURL, atomically: true, encoding: .utf8) } catch { print("error creating file") } }
I know I can write another function to create another
CSV
file with a single column to record the force, but I would like to record them in a single spreadsheet.Also, does anyone know how to remove the "Optional" in the
CSV
file created?This is what I have tried based on one of the answers.
func createCSVX(from recArray:[Dictionary<String, AnyObject>]) { var csvString = "\("Time"),\("Force")\n" dct.updateValue(TestDraw.time as AnyObject, forKey: "T") dct.updateValue(TestDraw.force as AnyObject, forKey: "F") patientsData.append(dct) csvString = csvString.appending("\(String(describing: dct["T"])), \(String(describing: dct["F"]))\n") let fileManager = FileManager.default do { let path = try fileManager.url(for: .documentDirectory, in: .allDomainsMask, appropriateFor: nil , create: false ) let fileURL = path.appendingPathComponent("TrailTime.csv") try csvString.write(to: fileURL, atomically: true , encoding: .utf8) } catch { print("error creating file") } print(TestDraw.force) }
-
Fëanor Tang over 4 yearsI have tried what you suggested, but unfortunately, the data in Force all go into the Time column. Would you please take a look at the change I made in the original question and point out what goes wrong?
-
Rahmouni Rabii over 4 yearsyou forgot the ! at the end to remove optional csvString = csvString.appending("(String(describing: dct["T"]!)), (String(describing: dct["F"]!))\n")
-
Fëanor Tang over 4 yearsOh right, thanks! But why all the 0 is under Time, instead of Force, where it is supposed to be
-
Protocol about 3 yearsfrom above csv is comma separated file. But if any string is itself contains comma then this fails. Please suggest any way to overcome that
-
user4150758 almost 2 yearswhere could we find the file? I can't see it in Files app
-
user4150758 almost 2 yearswhere could we find the file? I can't see it in Files app