1

我有一个包含一些数据的 excel 文件(具有多列和多行)。我想将此数据导入我的基于核心数据的数据库中。我正在努力导入数据,因为单元格中的文本包含换行符。

我尝试了以下方法:

1.) 将 excel 导出到制表符分隔的文本文件

2.) 在 iOS 中编写一个导入路由,使用以下代码读取制表符分隔的文本文件:

NSCharacterSet *tabCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@"\t"];

NSArray *rows = [dataString componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
NSArray *columns = [row componentsSeparatedByCharactersInSet:tabCharacterSet];

问题:我有 1000 个,每个rows有 15columns个。解析例程返回大于 1000rows且小于 15 columns。解析例程没有正确处理单元格中的换行符。

如果我使用,我会得到相同的结果

[NSCharacterSet characterSetWithCharactersInString:@"\r\n"];

或者

[NSCharacterSet characterSetWithCharactersInString:@"\r"];

代替

[NSCharacterSet newlineCharacterSet]

但如果我使用它会完全失败

[NSCharacterSet characterSetWithCharactersInString:@"\n"];

如何正确解析 excel 数据?

也许我可以使用正则表达式来获取线组件?任何想法/指针?

更新(示例 XLSX 和导出文件):

示例 XLSX 文件 示例 TAB 分隔文本文件

4

1 回答 1

0

对我有用的解决方案涉及使用NSScanner类。

- (NSArray *)parseCSVFileString {
    NSMutableArray *rows = [NSMutableArray array];

    // Get newline character set
    NSMutableCharacterSet *newlineCharacterSet = (id)[NSMutableCharacterSet whitespaceAndNewlineCharacterSet];
    [newlineCharacterSet formIntersectionWithCharacterSet:[[NSCharacterSet whitespaceCharacterSet] invertedSet]];

    // Characters that are important to the parser
    NSMutableCharacterSet *importantCharactersSet = (id)[NSMutableCharacterSet characterSetWithCharactersInString:@",\""];
    [importantCharactersSet formUnionWithCharacterSet:newlineCharacterSet];

    // Create scanner, and scan string
    NSScanner *scanner = [NSScanner scannerWithString:self];
    [scanner setCharactersToBeSkipped:nil];

    while (![scanner isAtEnd]) {

        @autoreleasepool {
            BOOL insideQuotes = NO;
            BOOL finishedRow = NO;
            NSMutableArray *columns = [NSMutableArray arrayWithCapacity:10];
            NSMutableString *currentColumn = [NSMutableString string];
            while ( !finishedRow ) {
                NSString *tempString;

                if ([scanner scanUpToCharactersFromSet:importantCharactersSet intoString:&tempString]) {
                    [currentColumn appendString:tempString];
                }

                if ([scanner isAtEnd]) {

                    if (![currentColumn isEqualToString:@""]) [columns addObject:currentColumn];

                    finishedRow = YES;

                } else if ([scanner scanCharactersFromSet:newlineCharacterSet intoString:&tempString]) {

                    if (insideQuotes) {
                        // Add line break to column text
                        [currentColumn appendString:tempString];

                    } else {
                        // End of row
                        if (![currentColumn isEqualToString:@""]) [columns addObject:currentColumn];

                        finishedRow = YES;
                    }

                } else if ([scanner scanString:@"\"" intoString:NULL]) {

                    if (insideQuotes && [scanner scanString:@"\"" intoString:NULL]) {
                        // Replace double quotes with a single quote in the column string.
                        [currentColumn appendString:@"\""];

                    } else {
                        // Start or end of a quoted string.
                        insideQuotes = !insideQuotes;
                    }

                } else if ([scanner scanString:@"," intoString:NULL]) {

                    if (insideQuotes) {
                        [currentColumn appendString:@","];

                    } else {
                        // This is a column separating comma
                        [columns addObject:currentColumn];
                        currentColumn = [NSMutableString string];
                        [scanner scanCharactersFromSet:[NSCharacterSet whitespaceCharacterSet] intoString:NULL];
                    }
                }
            }

            if ( [columns count] > 0 ) [rows addObject:columns];
        }
    }

    return rows;
}

参考: http: //www.macresearch.org/cocoa-scientists-part-xxvi-parsing-csv-data

于 2013-01-23T04:21:00.970 回答