2016-01-24 2 views
0

Я сохраняю CSV-файл и отправляю его по электронной почте. Он работает, но CSV не отформатирован правильно. Некоторые элементы, которые нужно перенести в новую строку, включают второй столбец существующей строки. Есть 5 столбцов, идентификатор, имя, модель, взлеты и цена. Есть ли что-то, что я сделал неправильно при создании файла?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-библиотеку, которая должным образом обрабатывает все эти случаи.

Смежные вопросы