Domanda

Part of my iOS app will include exporting a .csv file.

I have the file made and data is added to each row as I would like.

I would like to add a header row so if a file is emailed to a person they will know what each column is for.

How do I implement something like this?

Here is my csv code below:

- (NSString *)dataFilePath
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    return [documentsDirectory stringByAppendingPathComponent:@"myfile.csv"];
}

- (IBAction)save:(id)sender
{
    if (![[NSFileManager defaultManager] fileExistsAtPath:[self dataFilePath]]) {
        [[NSFileManager defaultManager] createFileAtPath: [self dataFilePath] contents:nil attributes:nil];
    }

    NSString * writeString = [NSString stringWithFormat:@"%@,%@,%@\n", self.nameTextField.text, self.cityTextField.text, self.stateTextField.text];

    NSFileHandle *handle;
    handle = [NSFileHandle fileHandleForWritingAtPath: [self dataFilePath]];
    [handle truncateFileAtOffset:[handle seekToEndOfFile]];
    [handle writeData:[writeString dataUsingEncoding:NSUTF8StringEncoding]];

    self.nameTextField.text = @"";
    self.cityTextField.text = @"";
    self.stateTextField.text = @"";

    [self.stateTextField resignFirstResponder];
}

Questions 2:

How can I write over a row? Currently if I update any of the UITextFields a new row is added.

È stato utile?

Soluzione

A header row in a CSV file is simply fixed data in the first row - it is up to the program that reads the CSV file to treat the first row as a header row - Excel has an option in the file open/import dialog, for example.

In your code you can simply write the header when you first create the file -

- (IBAction)save:(id)sender
{
    NSString *headerRow;
    if (![[NSFileManager defaultManager] fileExistsAtPath:[self dataFilePath]]) {
        [[NSFileManager defaultManager] createFileAtPath: [self dataFilePath] contents:nil attributes:nil];
        headerRow=@"name,city,state";
    }

    NSString * writeString = [NSString stringWithFormat:@"%@,%@,%@\n", self.nameTextField.text, self.cityTextField.text, self.stateTextField.text];

    NSFileHandle *handle;
    handle = [NSFileHandle fileHandleForWritingAtPath: [self dataFilePath]];
    [handle truncateFileAtOffset:[handle seekToEndOfFile]];
    if (headerRow != nil) {
        [handle writeData:[headerRow dataUsingEncoding:NSUTF8StringEncoding]];
    }
    [handle writeData:[writeString dataUsingEncoding:NSUTF8StringEncoding]];

    self.nameTextField.text = @"";
    self.cityTextField.text = @"";
    self.stateTextField.text = @"";

    [self.stateTextField resignFirstResponder];
}

Altri suggerimenti

Right away you need to know that adding something to a CSV file makes it not a CSV file. Exporting with comments will work if you're also the only one importing it - in which case it is your custom data format based on CSV. There is a defined IETF standard for CSV - RFC4180.

To make it work you would need to define some escape character that informs your format parser that a line is a comment. I suggest "", - this will never normally appear in a RFC4180-compliant CSV file.

In practical terms, add your comment lines after each CSV-compliant line. In your save: method you have only one line so it will work to write a comment line and then the RFC-compliant line or in the opposite order, as long as you preserve the integrity of the RFC lines. If you ever want to save a longer string with many lines, you would need to split the NSString you are saving with something like

- (NSArray *)componentsSeparatedByString:(NSString *)separator

where your separator is a "\n", and then loop through the resulting array to write each line, adding your comments as required.

You can use a regular CSV parser still (like CHCSVParser) if you preprocess the file and strip out the lines beginning with your special comment marker. Again you would need to split the incoming file by line break and discard the comments before trying to parse it.

THANK YOU Dave DeLong for CHCSVParser! I use it often.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top