如何使用Swift创建CSV文件

12

我创建了一个应用程序来收集从 Apple pencil 输入的数据,尝试将数据导出到 CSV 文件中。但迄今为止,我只能创建一个记录时间长度的单个列。我想添加另一列以记录 Apple pencil 的力量。

这是我尝试做的:

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")
    }

}

我知道我可以编写另一个函数来创建仅包含一列以记录力的CSV文件,但是我想将它们记录在单个电子表格中。 此外,有人知道如何删除所创建的CSV文件中的“Optional”吗? 这是我基于其中一个答案尝试过的内容。
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)

}

Screeshot of the exported CSV file


1
使用这个库CHCSVParser,创建一个csv非常容易。 - Alastar
它已经在Swift库中了吗?可以直接导入吗? - Fëanor Tang
不,你应该以这种方式将其添加到你的Podfile中:pod 'CHCSVParser'。 - Alastar
哇,谢谢!我稍后会研究一下如何使用CocoaPods。我是Swift的新手,以前不知道CocoaPods。 - Fëanor Tang
使用这个指南,非常简单:https://www.raywenderlich.com/626-cocoapods-tutorial-for-swift-getting-started - Alastar
甚至不必使用CocoaPods。我通过跟随这个神奇的教程,成功地在一个原始的SwiftUI项目中运行了CHCSVParser: https://youtu.be/7luhStOgXjk 你只需要将存储库中的两个文件复制到你的项目目录中即可。 - Dan
2个回答

19

Tutorial来自https://iostutorialjunction.com/2018/01/create-csv-file-in-swift-programmatically.html

第一步:

创建一个数组,名为“employeeArray”,它将存储员工的所有记录作为键值对象。同时我们将向新创建的数组添加虚拟数据。

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)
        }
    }
}

步骤2:现在我们有了数据,是时候使用Swift编程动态创建CSV(逗号分隔值)文件了。为此,我们将循环遍历“employeeArray”中的记录,并将它们附加到一个字符串中。然后,我们将这个字符串写入应用程序的文档目录中。所有的操作都在名为“createCSV”的不同函数中进行,以下是相应的代码:

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")
        }

    }

步骤三:最后,我们将从“viewDidLoad”中调用我们的函数。下面是完整的代码。

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")
        }

    }
 }

我已经尝试了您建议的方法,但不幸的是,Force中的所有数据都进入了Time列。您能否请看一下我在原问题中所做的更改,并指出哪里出了问题? - Fëanor Tang
你忘了在结尾加上感叹号以删除可选项。 csvString = csvString.appending("(String(describing: dct["T"]!)), (String(describing: dct["F"]!))\n") - Rahmouni Rabii
哦,好的,谢谢!但是为什么所有的0都在时间下面,而不是应该在力量下面呢? - Fëanor Tang
1
从上述CSV文件可知,它是以逗号分隔的文件。但如果任何字符串本身包含逗号,则此方法将失败。请建议克服这个问题的方法。 - Protocol
1
我们在哪里可以找到这个文件?我在文件应用程序中看不到它。 - user4150758

2

以上回答很好,我稍作修改以解决数据中的特定情况。您可以根据需要修改各个组件,并删除逗号、修剪UUID等。请注意,此解决方案使用存储在Core Data对象列表中的事务。我还打印数据文件的位置,以便您可以在模拟器中进行检查。

  func createCSVFile() {
        var csvString = "id,name,description,category,date,type,receipt,amount\n"
        for trans in transactions {
            let transID = trans.id!.debugDescription.split(separator: "-")[0].replacingOccurrences(of: ")", with: "")
            let transName = trans.name!
            let transDesc = trans.desc!.replacingOccurrences(of: ",", with: "-")
            let transCat = trans.category!
            let transDate = trans.date!
            let transType = trans.type!
            
            var transReceipt = "None"
            if trans.receipt == nil {
                transReceipt = "Present"
            }
            let transAmount = trans.amount
            let dataString = "\(transID),\(transName),\(transDesc),\(transCat),\(transDate),\(transType),\(transReceipt),\(transAmount)\n"
            print("DATA: \(dataString)")
            csvString = csvString.appending(dataString)
        }

        let fileManager = FileManager.default
        do {
            let path = try fileManager.url(for: .documentDirectory, in: .allDomainsMask, appropriateFor: nil, create: false)
            print("PATH: \(path)")
            let fileURL = path.appendingPathComponent("CSVData.csv")
            try csvString.write(to: fileURL, atomically: true, encoding: .utf8)
        } catch {
            print("error creating file")
        }
    }

1
我们应该在哪里找到这个文件?我在文件应用程序中找不到它。 - user4150758

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接