예제 #1
0
        /// <summary>
        /// Parses CSV file. and returns <seealso cref="CsvReader"/> initialized with the content.
        /// </summary>
        /// <param name="csvFilePath">
        /// The CSV file path.
        /// </param>
        /// <param name="hasHeader">
        /// Indicates if the file has a header.
        /// </param>
        /// <param name="options">
        /// The options.
        /// </param>
        /// <returns>
        /// The <seealso cref="CsvReader"/> initialized with the content of the CSV <paramref name="csvFilePath"/>.
        /// </returns>
        public static CsvReader Parse(string csvFilePath, bool hasHeader = true, CsvReaderOptions options = null)
        {
            var stream = File.OpenRead(csvFilePath);

            return(new CsvReader()
            {
                stream = stream,
                Rows = Parse(stream, hasHeader, options)
            });
        }
예제 #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CsvRow"/> class.
        /// </summary>
        /// <param name="headers">
        /// The headers.
        /// </param>
        /// <param name="values">
        /// The values.
        /// </param>
        /// <param name="options">
        /// The options.
        /// </param>
        // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local
        public CsvRow(List <string> headers, List <string> values, CsvReaderOptions options)
        {
            if (options.StrictCellCount && headers.Count != values.Count)
            {
                throw new CsvInvalidCellCountException(headers.Count, values.Count);
            }

            for (int i = 0; i < headers.Count; i++)
            {
                string header = headers[i];
                this.values.Add(header, values.Count > i ? values[i] : string.Empty);
            }
        }
예제 #3
0
        /// <summary>
        /// Parse CSV file to list of dynamic objects.
        /// </summary>
        /// <param name="input">
        /// The input CSV stream.
        /// </param>
        /// <param name="hasHeader">
        /// Indicates if the file has a header.
        /// </param>
        /// <param name="options">
        /// The options.
        /// </param>
        /// <returns>
        /// The list of dynamic objects produced from CSV lines.
        /// </returns>
        public static IEnumerable <dynamic> Parse(Stream input, bool hasHeader = true, CsvReaderOptions options = null)
        {
            if (options == null)
            {
                options = new CsvReaderOptions();
            }

            using (TextReader reader = new StreamReader(input))
            {
                char separator = options.Separator;

                List <string> headers = new List <string>();

                if (hasHeader)
                {
                    HashSet <string> duplicateHeaderTracker = new HashSet <string>();
                    var headerRowComponents = CsvParser.ParseLine(reader, options.Separator).ToList();
                    if (!headerRowComponents.Any())
                    {
                        yield break;
                    }

                    for (int i = 0; i < headerRowComponents.Count; i++)
                    {
                        string currentHeader = TransformHeaderNameToPropertyName(headerRowComponents[i], options.HeaderMatchRegex ?? MatchSurroundingQuotes);
                        currentHeader = AllowedHeaderNames.IsMatch(currentHeader) ? currentHeader : null;
                        if (options.ResolveHeaderName != null)
                        {
                            var currentHeaderReplacement = options.ResolveHeaderName(
                                headerRowComponents[i],
                                currentHeader);

                            currentHeader = string.IsNullOrEmpty(currentHeaderReplacement)
                                                ? currentHeader
                                                : currentHeaderReplacement;
                        }

                        if (string.IsNullOrEmpty(currentHeader) || duplicateHeaderTracker.Contains(currentHeader))
                        {
                            currentHeader = $"Column{i}";
                        }

                        duplicateHeaderTracker.Add(currentHeader);
                        headers.Add(currentHeader);
                    }
                }

                List <string> values = CsvParser.ParseLine(reader, separator).ToList();
                while (values.Any())
                {
                    if (!headers.Any())
                    {
                        headers = new List <string>();
                        var headerCount = values.Count;
                        for (int i = 0; i < headerCount; i++)
                        {
                            headers.Add($"Column{i}");
                        }
                    }

                    dynamic lineObject = new CsvRow(headers, values, options);
                    yield return(lineObject);

                    values = CsvParser.ParseLine(reader, separator).ToList();
                }
            }
        }