【问题标题】:How to import an excel file that contains line breaks with-in the cell text如何在单元格文本中导入包含换行符的excel文件
【发布时间】:2012-12-06 04:56:29
【问题描述】:

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

我尝试了以下方法:

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

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

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

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

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

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

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

[NSCharacterSet characterSetWithCharactersInString:@"\r"];

而不是

[NSCharacterSet newlineCharacterSet]

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

[NSCharacterSet characterSetWithCharactersInString:@"\n"];

如何正确解析 excel 数据?

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

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

【问题讨论】:

  • 您能否举例说明 TSV 文件在一行内部中的外观?
  • CSV/TSV 值中包含换行符的值将用引号括起来。包含字段分隔符的值也将用引号引起来。您无法通过简单的分隔符拆分文本来正确解析 CSV/TSV 文件。您需要处理引用的值。正确解析 CSV/TSV 文件比大多数人认为的要复杂得多。
  • 已编辑,包括示例 XLSX 和导出文件屏幕截图。
  • 如果可能的话,我建议使用通过 ADODB 连接到您的数据库的 excel 宏,性能可能不会很好,但它应该正确包装单元格换行符,以便正确上传进入数据库。
  • 您也可以使用开源 ObjectiveC 框架直接从 xls 文件中读取值:github.com/dhoerl/DHlibxls

标签: ios excel parsing


【解决方案1】:

对我有用的解决方案是使用 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

【讨论】:

    猜你喜欢
    • 2010-09-25
    • 1970-01-01
    • 1970-01-01
    • 2014-11-19
    • 1970-01-01
    • 2015-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多