Esempio n. 1
0
        /**************************************************************************/
        static int Main(string[] args)
        {
            HtmlDocument doc;
            string       in_file    = "";
            string       price_file = "";
            string       out_file   = "";

            bool ShowAutoFilter = true;

            /*----------------------------------------------------------------------------*/
            if (args.Length == 0)
            {
                Console.WriteLine("SberHTMLParser <path to Html file> [path to prices file]");
                return(1);
            }
            else
            {
                //
                in_file = args[0];
                if (!File.Exists(in_file))
                {
                    Console.WriteLine($"File {in_file} does not exists");
                    return(1);
                }

                // если есть файл с ценами, то будет пробовать заполнить таьлички Prices и Rates !
                // файл должен иметь определенную структуру.
                if (args.Length == 2)
                {
                    price_file = args[1];
                    if (File.Exists(price_file))
                    {
                        prices = new Prices(price_file);
                        prices.calculate();
                        if (!prices.I.IsEmpty)
                        {
                            va.tables_list.Add(prices.I);
                        }
                        if (!prices.C.IsEmpty)
                        {
                            va.tables_list.Add(prices.C);
                        }
                    }
                }
            }
            out_file = in_file.Replace(Path.GetExtension(in_file), ".xlsx");
            /*----------------------------------------------------------------------------*/

            // загружаем документ в строку
            // изначально всё должно быть в кодировке UTF-8 и по-русски
            // но, если файл был сохранен в кодировке windows-1251, то это надо бы явно указать
            // считываем файл в строку сначала без преобразования и попробуем найти фразу "Отчет брокера"
            // если не находим, то пробуем переключиться в windows-1251
            va.html = File.ReadAllText(in_file);
            if (!va.html.Contains("Отчет брокера", StringComparison.OrdinalIgnoreCase))
            {
                Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
                va.html = File.ReadAllText(in_file, Encoding.GetEncoding("windows-1251"));
                if (!va.html.Contains("Отчет брокера", StringComparison.OrdinalIgnoreCase))
                {
                    Console.WriteLine($"Файл {in_file} в неизвестной кодировке");
                    return(1);
                }
            }
            // убираем из документа <TBODY> и </TBODY>. Нам при парсинге таблиц они не нужны. В разных вариантах брокерского отчета эти теги или есть или нет.
            va.html = va.html.Replace("<tbody>", "", StringComparison.OrdinalIgnoreCase).Replace("</tbody>", "", StringComparison.OrdinalIgnoreCase);

            // парсим документ и создаем массив из всех таблиц
            ParseHtmlSplitTables();

            // узнаем период отчета и дату создания. очень приблизительно предполагаем, что это строка
            // <br>за период с dd.MM.YYYY по dd.MM.YYYY, дата создания dd.MM.YYYY</br>
            string pattern = "дата создания";

            if (Regex.IsMatch(va.html, pattern))
            {
                Match  match = Regex.Matches(va.html, pattern).First();
                string s     = va.html.Substring(match.Index - 30, 62);

                var regex = new Regex(@"\b\d{2}\.\d{2}.\d{4}\b");
                foreach (Match m in regex.Matches(s))
                {
                    DateTime dt;
                    if (DateTime.TryParseExact(m.Value, "dd.MM.yyyy", null, DateTimeStyles.None, out dt))
                    {
                        va.report_dates.Add(dt);
                    }
                }
            }

            /*----------------------------------------------------------------------------*/
            // парсим каждую таблицу по отдельности сверяясь со списком из конфигурационнго файла
            foreach (var t in htmlTables)
            {
                Table T = null;
                doc = new HtmlDocument();
                doc.LoadHtml(t);
                var nodes = doc.DocumentNode.SelectNodes("//table/tr");

                // список таблиц и параметры парсинга заголовков для определения имени таблицы
                string[] v = ConfigurationManager.AppSettings.AllKeys.Where(key => key.StartsWith("tables")).Select(key => ConfigurationManager.AppSettings[key]).ToArray();;
                foreach (string s in v)
                {
                    var    e               = s.Split(';');
                    string table_name      = e[0];
                    int    h_row           = Convert.ToInt32(e[1]);
                    int    h_length        = Convert.ToInt32(e[2]);
                    string columns         = e[3];
                    string columns_content = e[4];

                    var header = nodes[h_row].Elements("td").Select(td => td.InnerText.Trim()).ToArray();

                    if (header.Length == h_length)
                    {
                        int found = 0;
                        var c     = columns.Split('#');
                        for (int ii = 1; ii <= c.Length; ii++)
                        {
                            if (header[Convert.ToInt32(c[ii - 1])].Contains(columns_content.Split('#')[ii - 1]))
                            {
                                found++;
                            }
                        }
                        if (found == c.Length)
                        {
                            T = new Table(table_name);
                        }
                    }
                }

                if (T != null && !T.IsEmpty)
                {
                    T.addrows_from_nodes(nodes);
                    va.tables_list.Add(T);
                }
            }
            /*----------------------------------------------------------------------------*/


            // worksheet "Позиция"
            Position p = new Position(va, prices);

            va.tables_list.Add(p.T);
            p.calculate();

            // worksheet "PL"
            PL pl = new PL(va, prices);

            va.tables_list.Add(pl.T);
            pl.calculate();


            /*----------------------------------------------------------------------------*/
            // export to excel
            /*----------------------------------------------------------------------------*/
            var wb = new XLWorkbook();

            // worksheet "Даты"
            IXLWorksheet ws;

            ws = wb.Worksheets.Add("Даты");
            int i = 1;

            foreach (DateTime d in va.report_dates)
            {
                if (i == 1)
                {
                    ws.Cell(i, 1).Value = "Начало периода";
                }
                if (i == 2)
                {
                    ws.Cell(i, 1).Value = "Конец периода";
                }
                if (i == 3)
                {
                    ws.Cell(i, 1).Value = "Дата создания отчета";
                }
                ws.Cell(i, 2).Value = d.ToString();
                i++;
            }
            ws.Columns().AdjustToContents();


            // worksheets from list of tables
            foreach (Table t in va.tables_list.OrderBy(o => o.Order))
            {
                if (!t.IsEmpty)
                {
                    ws = wb.Worksheets.Add(t.table, t.WorksheetName);

                    /*----------------------------------------------------------------------------*/
                    // добавление формул
                    int c_col = 1;
                    foreach (DataColumn c in t.table.Columns)
                    {
                        if (c.ExtendedProperties.Count != 0)
                        {
                            var rngData = ws.Range(2, c_col, t.table.Rows.Count + 1, c_col);
                            rngData.LastColumn().FormulaR1C1 = c.ExtendedProperties["Formula"].ToString();
                        }
                        c_col++;
                    }

                    /*----------------------------------------------------------------------------*/
                    // format columns
                    for (int a = 0; a <= t.table.Columns.Count - 1; a++)
                    {
                        if (t.table.Columns[a].DataType == System.Type.GetType("System.Double"))
                        {
                            ws.Columns(a + 1, a + 1).Style.NumberFormat.Format = "#,##0.00";
                        }
                    }

                    ws.Row(1).Style.Alignment.SetHorizontal(XLAlignmentHorizontalValues.Center);
                    ws.Row(1).Style.Alignment.SetVertical(XLAlignmentVerticalValues.Top);
                    ws.Tables.FirstOrDefault().ShowAutoFilter = ShowAutoFilter;
                    ws.Columns().AdjustToContents();
                }
            }

            // save file
            wb.SaveAs(out_file);
            /*----------------------------------------------------------------------------*/

            return(0);
        }
Esempio n. 2
0
 /******************************************************************/
 public Position(Variables va, Prices prices)
 {
     this.va     = va;
     this.prices = prices;
     T           = new Table("position");
 }
Esempio n. 3
0
 /******************************************************************/
 public PL(Variables va, Prices prices)
 {
     this.va     = va;
     this.prices = prices;
     T           = new Table("PL");
 }