2016-01-24 131 views
0

我正在保存CSV文件並通過電子郵件發送。它可以工作,但CSV格式不正確。應該移動到新行的一些項目包含在現有行的第二列中。有5列,id,名稱,型號,ups和價格。有什麼我創建文件時做錯了嗎?CSV格式不正確

func openActions() { 
     actions = UIAlertController(title: "", message: "", preferredStyle: .ActionSheet) 
     let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: { 
      (action) -> Void in 
      self.actions?.dismissViewControllerAnimated(true, completion: nil) 
     }) 

     let saveCSV = UIAlertAction(title: "Save as CSV", style: .Default, handler: { 
      (action) -> Void in 
      self.getAndSaveItems() 
      self.actions?.dismissViewControllerAnimated(true, completion: nil) 
     }) 

     let viewFile = UIAlertAction(title: "View CSV", style: .Default, handler: { 
      (action) -> Void in 
      self.viewFile() 
      self.actions?.dismissViewControllerAnimated(true, completion: nil) 
     }) 

     let emailFile = UIAlertAction(title: "Email CSV", style: .Default, handler: { 
      (action) -> Void in 
      self.emailFile() 
      self.actions?.dismissViewControllerAnimated(true, completion: nil) 
     }) 

     actions?.addAction(cancelAction) 
     actions?.addAction(emailFile) 
     actions?.addAction(viewFile) 
     actions?.addAction(saveCSV) 
     self.presentViewController(actions!, animated: true, completion: nil) 
    } 

    func dataFilePath() -> String { 
     let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) 
     let documentsDirectory = paths[0] 
     let titleString = self.title!.stringByReplacingOccurrencesOfString(" ", withString: "_") 
     let string = String(format: "/%@.csv", titleString) 
     return documentsDirectory.stringByAppendingString(string) 
    } 

    func getAndSaveItems() { 
     let getLimit = 1000 
     var getSkip = 0 

     activityIndicator?.startAnimating() 

     let query = PFQuery(className: "Items") 
     query.whereKey("user", equalTo: PFUser.currentUser()!) 
     query.whereKey("collection", equalTo: self.title!) 
     query.orderByAscending("item") 
     query.limit = getLimit 
     query.skip = getSkip 
     query.findObjectsInBackgroundWithBlock({ 
      (objects, error) -> Void in 
      if error == nil { 
       if let objects = objects as [PFObject]! { 
        for object in objects { 
         self.names.append(object["item"] as! String) 
         self.upcs.append(object["upc"] as! String) 
         self.ids.append(object.objectId!) 
         self.models.append(object["model"] as! String) 
         self.prices.append(object["pricePaid"] as! String) 
         if object["notes"] == nil { 
          self.notes.append(nil) 
         } else { 
          self.notes.append(object["notes"] as? String) 
         } 
        } 
       } 

       if objects!.count == getLimit { 
        getSkip += getLimit 
        self.getAndSaveItems() 
       } 
      } else { 
       // Show error... 
      } 
     }) 

     writeToFile() 
    } 

    func writeToFile() { 
     if (!NSFileManager.defaultManager().fileExistsAtPath(self.dataFilePath())) { 
      NSFileManager.defaultManager().createFileAtPath(self.dataFilePath(), contents: nil, attributes: nil) 
     } 

     // var writeString = NSMutableString(capacity: 0) 
     var writeString = String() 
     writeString.reserveCapacity(0) 

     for (var i = 0; i < names.count; i++) { 
      let stringToWrite = String(format: "%@,%@,%@,%@,%@, \n", ids[i], names[i], models[i], upcs[i], prices[i]) 
      writeString.appendContentsOf(stringToWrite) 
     } 

     let handle = NSFileHandle(forWritingAtPath: self.dataFilePath()) 
     handle?.truncateFileAtOffset((handle?.seekToEndOfFile())!) 
     handle?.writeData(writeString.dataUsingEncoding(NSUTF8StringEncoding)!) 

     self.activityIndicator?.stopAnimating() 
    } 

    func viewFile() { 
     if (NSFileManager.defaultManager().fileExistsAtPath(dataFilePath())) { 
      let fileData = NSData(contentsOfFile: dataFilePath()) 

      let fileVC = FileViewController(nibName: "FileViewController", bundle: nil) 
      let navController = NavController(rootViewController: fileVC) 
      fileVC.fileData = fileData 
      self.presentViewController(navController, animated: true, completion: nil) 
     } else { 
      // File doesn't exist... 
      print("File doesn't exist") 
     } 
    } 

    func emailFile() { 
     if (NSFileManager.defaultManager().fileExistsAtPath(dataFilePath())) { 
      if MFMailComposeViewController.canSendMail() { 
       let mailComposer = MFMailComposeViewController() 
       mailComposer.mailComposeDelegate = self 
       let subject = String(format: "My %@ Collection", self.title!) 
       mailComposer.setSubject(subject) 
       mailComposer.setMessageBody("", isHTML: false) 

       let fileData = NSData(contentsOfFile: dataFilePath()) 
       let titleString = self.title!.stringByReplacingOccurrencesOfString(" ", withString: "_") 
       let fileNameString = String(format: "%@.csv", titleString) 
       mailComposer.addAttachmentData(fileData!, mimeType: "text/csv", fileName: fileNameString) 

       self.presentViewController(mailComposer, animated: true, completion: nil) 
      } else { 
       // Can't send mail... 
      } 
     } else { 
      // File doesn't exist... 
      print("File doesn't exist") 
     } 
    } 

    func mailComposeController(controller: MFMailComposeViewController, didFinishWithResult result: MFMailComposeResult, error: NSError?) { 
     self.dismissViewControllerAnimated(true, completion: nil) 
    } 

enter image description here

回答

1

這條線:

let stringToWrite = String(format: "%@,%@,%@,%@,%@, \n", ids[i], names[i], models[i], upcs[i], prices[i]) 

是您正在使用創建CSV文件的每一行的內容。這隻適用於簡單的情況。

下面是CSV規則:

  1. 如果字段值包含字段分隔符(逗號你的情況),報價,空格處的值的任一端,或任何換行符的字段值必須用引號括起來(通常用雙引號)。
  2. 如果字段值包含任何引號字符,則必須用另一引號字符轉義每個引號字符。

創建和解析CSV文件比大多數人意識到的要複雜得多。

要麼修改您的邏輯來添加任何所需的引用或找到正確處理所有這些情況的第三方CSV庫。