Advertisement
eLVik

Form1

Dec 2nd, 2021
576
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 25.23 KB | None | 0 0
  1. //#define DEBUG_LOG
  2.  
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Data.Objects;
  7.  
  8. using GUTFIRK.ForestManagement.Domain.ModelEntities;
  9. using GUTFIRK.ForestManagement.Domain;
  10. using GUTFIRK.Utils;
  11. using GUTFIRK.ForestManagement.Domain.ReportServiceInterface;
  12. using GUTFIRK.ForestManagement.Domain.ReportServiceInterface.ReportsDescriptions.ForestFund;
  13. using GUTFIRK.ForestManagement.Domain.ReportServiceInterface.ReportsParams;
  14.  
  15. using GUTFIRK.Utils.TemplateSystem;
  16.  
  17. namespace GUTFIRK.ForestManagement.ReportService.ReportsCreators
  18. {
  19.     /// <summary>
  20.     /// Класс, формирующий отчет "Форма №1" по инструкциям ГУЛФ 1997 года.
  21.     /// </summary>    
  22.     public class Form1_ReportCreator : SelectOptionsAdapter
  23.     {
  24.         // Максимальное количество строк данных на одной странице
  25.         //const int MAX_ROW_COUNT = 14;
  26.         // Количество граф в форме + 1
  27.         const int COLUMN_COUNT = 25;
  28.  
  29.         //object _lockObject = new object();
  30.  
  31.         ForestResourcesReportParams _reportParams = null;
  32.         List<short> _distinctNormativeDataList = new List<short>();
  33.         // Список строк формы учета.
  34.         List<Form1Row> _form1RowsList = null;
  35.         // Массив для хранения результатов расчета
  36.         double[,] _s = null;
  37.  
  38.         // Площади горных и равнинных лесов
  39.         double _sg1 = 0.0, _sg2 = 0.0;
  40.  
  41.         /// <summary>
  42.         /// Конструктор.
  43.         /// </summary>
  44.         public Form1_ReportCreator()
  45.         {
  46.             _description = new Form1_ReportDescription();
  47.         }
  48.  
  49.         /// <summary>
  50.         /// Расчеты
  51.         /// </summary>
  52.         /// <param name="reportParams">Параметры отчета</param>
  53.         /// <param name="progressCallback">Процедура, выполняющая обновление прогресса.</param>
  54.         /// <returns>Результаты расчетов</returns>
  55.         public override object DoCalculations(IReportParams reportParams, Procedure<int> progressCallback)
  56.         {
  57.             CheckParams(reportParams);
  58.             #region Переменные
  59.             //Form1ReportData reportData = new Form1ReportData();
  60.  
  61. #if DEBUG_LOG
  62.             Program.LogSystem.Info("F1_get_params");
  63. #endif
  64.             _reportParams = (ForestResourcesReportParams)reportParams;
  65.             var year = (short)_reportParams.SelectOptions.YearOfActualization;
  66.  
  67.             // Переменные для учета рельефа местности
  68.             //double sg1 = 0.0;                // горные леса
  69.             //double sg2 = 0.0;                // равнинные леса
  70.  
  71. #if DEBUG_LOG
  72.             Program.LogSystem.Info("F2_sort_identifiers");
  73. #endif
  74.             _distinctNormativeDataList.Clear();
  75.  
  76.             // В этот список помещаем все сущности Form1Columns, затрагиваемые наборами НСИ
  77.             IEnumerable<Form1Columns> form1ColumnsList = new List<Form1Columns>();
  78.  
  79.             // Здесь - соответствия между категориями защитности и строками формы №1
  80.             IEnumerable<Form1Rows_To_ProtectionCategories> form1Rows_categoriesList = new List<Form1Rows_To_ProtectionCategories>();
  81.  
  82.             // Список ассоциаций НСИ за указанный год.
  83.             List<NormativeAssociation> na_list = null;
  84.  
  85.             // По этому справочнику будут определены подчиненные строки формы учета.
  86.             List<Form1Rows_CalculationOrder> calc_list = null;
  87.  
  88.             // в список calcOrder_list поместим различные номера действий. Отсортируем его по возрастанию номера действия.
  89.             List<byte> calcOrder_list = new List<byte>();
  90.  
  91.             int progress_counter = 0;
  92.             int progress = 0;
  93.             double progress_q = 0.0;
  94.  
  95.             #endregion
  96.             using (ModelContext context = new ModelContext())
  97.             {
  98.  
  99.                 #region Загрузка основных справочников и классификаторов
  100.  
  101.                 //form1RowsList = context.Form1RowSet.Include("ExploitableForestGroup").OrderBy(a => a.PrintOrder).ToList<Form1Row>();
  102. #if DEBUG_LOG
  103.                 Program.LogSystem.Info("F3_load_references");
  104. #endif
  105.                 _form1RowsList = context.Form1RowSet.OrderBy(a => a.PrintOrder).ToList();
  106.                 //reportData.Form1RowList = form1RowsList;
  107.  
  108.                 // Загрузив данные из БД в список один раз, будем искать в нем соответствие между кварталом и набором НСИ.
  109.                 na_list = context.NormativeAssociationSet.Where("it.Year = @year", new ObjectParameter("year", year)).Include("NormativeData").Include("Forestry").ToList<NormativeAssociation>();
  110.  
  111.                 if (na_list.Count == 0)
  112.                     throw new ReportException(reportParams, "Список нормативных ассоциаций пуст.");
  113.  
  114.                 calc_list = context.Form1Rows_CalculationOrderSet.Include("Form1RowA").Include("Form1RowB").ToList<Form1Rows_CalculationOrder>();
  115.                 calcOrder_list.Clear();
  116.  
  117.                 foreach (Form1Rows_CalculationOrder item in calc_list)
  118.                 {
  119.                     if (calcOrder_list.Contains(item.CalcOrder) == false)
  120.                         calcOrder_list.Add(item.CalcOrder);
  121.                 }
  122.                 calcOrder_list.Sort();
  123.  
  124.                 _s = new double[COLUMN_COUNT, _form1RowsList.Count];
  125.  
  126.                 progressCallback(5);
  127.                 #endregion
  128.  
  129.                 var qIDs = GetQuarterIDs(_reportParams.SelectOptions);
  130.                 var fullQuarterIds = GetFullQuarterIDs(_reportParams.SelectOptions);
  131.                 progress_q = qIDs.Count > 0 ? 85.0 / qIDs.Count : 0.0;
  132.  
  133.                 foreach (int quarterID in qIDs)
  134.                 {
  135.                     #region Callback
  136.                     progress_counter++;
  137.                     progress = 5 + (int)(progress_q * progress_counter);
  138.                     progressCallback(progress);
  139.                     #endregion
  140.  
  141.                     var quarter = context.QuarterSet.Include("DivisionalForestry.Forestry").FirstOrDefault(x => x.OID == quarterID);
  142.                     if (quarter == null)
  143.                         continue;
  144.  
  145.                     List<int> sortedIdentifiers = null;
  146.                     if (fullQuarterIds.BinarySearch(quarterID) >= 0)
  147.                     {
  148.                         quarter.Stratums.Load();
  149.                         sortedIdentifiers = quarter.Stratums.Select(x => x.OID).ToList();
  150.                     }
  151.                     else
  152.                     {
  153.                         sortedIdentifiers = GetStratumIDsFromPartialQuarter(_reportParams.SelectOptions, quarterID);
  154.                     }
  155.                     sortedIdentifiers.Sort();
  156.  
  157.  
  158.                     #region Загрузка НСИ
  159.                     NormativeAssociation na = na_list.Where(a => a.Forestry.OID == quarter.GetForestry().OID).FirstOrDefault();
  160.  
  161.                     // Ошибка может возникнуть в случае, если лесничеству не сопоставлен набор НСИ в указанный год.
  162.                     if (na == null)
  163.                         throw new ReportException(reportParams, String.Format("Отсутствует набор НСИ для квартала (OID = {0})", quarter.OID));
  164.  
  165.                     // Подгружаем данные, если встретился новый набор НСИ.
  166.                     if (_distinctNormativeDataList.Contains(na.NormativeData.OID) == false)
  167.                     {
  168.                         _distinctNormativeDataList.Add(na.NormativeData.OID);
  169.  
  170.                         ObjectParameter parameter = new ObjectParameter("oid", na.NormativeData.OID);
  171.                         // Список столбцов (граф) формы, ассоциированных с текущим набором НСИ.
  172.                         List<Form1Columns> list1 = context.Form1ColumnsSet.Where("it.NormativeData.OID = @oid", parameter).Include("LandCategory").Include("NormativeData").ToList();
  173.                         form1ColumnsList = form1ColumnsList.Concat(list1);
  174.  
  175.                         List<Form1Rows_To_ProtectionCategories> list2 = context.Form1Rows_To_ProtectionCategoriesSet.Where("it.NormativeData.OID = @oid", parameter).Include("ProtectionCategory").Include("NormativeData").Include("Form1Row").ToList<Form1Rows_To_ProtectionCategories>();
  176.                         form1Rows_categoriesList = form1Rows_categoriesList.Concat(list2);
  177.                     }
  178.                     #endregion
  179.  
  180.                     #region Выполнение хранимой процедуры и обработка ошибок
  181.  
  182.                     List<vw_QuarterAgeDataItem> vw_AgeDataResult = null;
  183.                     //lock (_lockObject)
  184.                     //{
  185.                         int counter = 0;
  186.                         bool success = false;
  187.  
  188.                         //Попытка выполнить хранимые процедуры
  189.                         while (!success)
  190.                         {
  191.                             try
  192.                             {
  193.                                 counter++; // Увеличиваем значение счетчика
  194.                                 // Получаем возрастные характеристики на квартал.
  195.                                 vw_AgeDataResult = context.GetMainStockAgeDataOnQuarter(quarter.OID, na.NormativeData.OID, na.CuttingAgeKey, year).ToList();
  196.  
  197.                                 success = true; // Выполнение хранимой процедуры успешно
  198.                             }
  199.                             // В случае ошибки выполнения хранимой процедуры 10 раз подряд останавливаем формирование отчета
  200.                             catch
  201.                             {
  202.                                 if (counter >= 10) break;
  203.                             }
  204.                         }
  205.                         if (!success) throw new ReportException(reportParams, "Ошибка доступа к хранимой процедуре");
  206.  
  207.                     //}
  208.                     #endregion
  209.  
  210.                     #region Расчет строк, которые зависят только от категории защитности
  211.  
  212.                     List<CommonData> commonDataList = quarter.GetCommonDataList(context, year);
  213.  
  214.                     foreach (CommonData commonData in commonDataList)
  215.                     {
  216.                         vw_QuarterAgeDataItem ageDataItem = vw_AgeDataResult.First(a => a.CommonData_OID == commonData.OID);
  217.                         //if (ageDataItem.ReturnCode.HasValue && ageDataItem.ReturnCode.Value != 0)
  218.                         //    continue;
  219.                         if (sortedIdentifiers.BinarySearch(ageDataItem.Stratum_OID.Value) >= 0)
  220.                         {
  221.                             //double k = forestResourcesReportParams.Identifiers.Where(x => x.Identifier == ageDataItem.Stratum_OID).Select(y => y.Area).First();
  222.  
  223.                             // Учет рельефа местности.
  224.                             if (commonData.MountainFlag)
  225.                                 _sg1 += commonData.Area;
  226.                             else
  227.                                 _sg2 += commonData.Area;
  228.  
  229.                             if (commonData.LandCategoryReference.IsLoaded == false)
  230.                                 commonData.LandCategoryReference.Load();
  231.  
  232.                             if (commonData.ProtectionCategoryReference.IsLoaded == false)
  233.                                 commonData.ProtectionCategoryReference.Load();
  234.  
  235.                             if (commonData.ProtectionCategory.ForestGroupReference.IsLoaded == false)
  236.                                 commonData.ProtectionCategory.ForestGroupReference.Load();
  237.  
  238.                             Form1Columns column = form1ColumnsList.First(a => a.LandCategory.OID == commonData.LandCategory.OID && a.NormativeData.OID == na.NormativeData.OID);
  239.                             if (column == null)
  240.                                 throw new ReportException(reportParams, String.Format("Нет соответствующей графы для категории земель (OID = {0}). Квартал (OID = {1})", commonData.LandCategory.OID, quarter.OID));
  241.  
  242.                             // Строки, соответствующие текущей категории защитности.
  243.                             IEnumerable<Form1Rows_To_ProtectionCategories> list3 = form1Rows_categoriesList.Where(a => a.ProtectionCategory.OID == commonData.ProtectionCategory.OID && a.NormativeData.OID == na.NormativeData.OID);
  244.  
  245.                             // В column.ColumnNumber содержится номер графы, к которой нужно прибавить площадь
  246.                             foreach (Form1Rows_To_ProtectionCategories item in list3)
  247.                             {
  248.                                 int index = _form1RowsList.IndexOf(item.Form1Row);
  249.                                 _s[column.ColumnNumber, index] += commonData.Area;
  250.                             }
  251.  
  252.  
  253.                             // "Эксплуатируемые" строки (27, 32, 43)
  254.                             if (ageDataItem.IsExploitable.HasValue && ageDataItem.IsExploitable.Value == true && ageDataItem.ReturnCode.HasValue && ageDataItem.ReturnCode.Value == 0)
  255.                             {
  256.                                 Form1Row row = _form1RowsList.FirstOrDefault(a => a.OID == commonData.ProtectionCategory.ForestGroup.ExploitableForm1RowOID);
  257.                                 if (row == null)
  258.                                     throw new ReportException(reportParams, String.Format("Отсутствует строка формы учета №1 (OID = {0})", commonData.ProtectionCategory.ForestGroup.ExploitableForm1RowOID));
  259.  
  260.                                 int index = _form1RowsList.IndexOf(row);
  261.                                 _s[column.ColumnNumber, index] += commonData.Area;
  262.                             }
  263.  
  264.                         }
  265.  
  266.                         context.Detach(commonData);
  267.                     }
  268.                     #endregion
  269.  
  270.                     foreach (vw_QuarterAgeDataItem ageDataResult in vw_AgeDataResult)
  271.                         context.Detach(ageDataResult);
  272.  
  273.                     context.Detach(quarter);
  274.                 }
  275.  
  276.             }
  277.  
  278.             #region Расчет подчиненных строк
  279.             foreach (byte calcOrder in calcOrder_list)
  280.             {
  281.                 IEnumerable<Form1Rows_CalculationOrder> list4 = calc_list.Where(a => a.CalcOrder == calcOrder);
  282.                 foreach (Form1Rows_CalculationOrder item in list4)
  283.                 {
  284.                     int index_dest = _form1RowsList.IndexOf(item.Form1RowA);
  285.                     int index_src = _form1RowsList.IndexOf(item.Form1RowB);
  286.                     for (int i = 0; i < COLUMN_COUNT; i++)
  287.                         _s[i, index_dest] += _s[i, index_src];
  288.                 }
  289.             }
  290.             #endregion
  291.  
  292.             #region Суммирование площадей по графам
  293.             for (int i = 0; i < _form1RowsList.Count; i++)
  294.             {
  295.                 _s[2, i] = _s[2, i] + _s[3, i];
  296.                 _s[11, i] = _s[7, i] + _s[8, i] + _s[9, i] + _s[10, i];
  297.                 _s[12, i] = _s[2, i] + _s[4, i] + _s[5, i] + _s[6, i] + _s[11, i];
  298.                 _s[24, i] = _s[13, i] + _s[14, i] + _s[15, i] + _s[16, i] + _s[17, i] + _s[18, i] + _s[19, i] + _s[20, i] + _s[21, i] + _s[22, i] + _s[23, i];
  299.                 _s[1, i] = _s[12, i] + _s[24, i];
  300.  
  301.                 if (_form1RowsList[i].IsExploitable)
  302.                 {
  303.                     for (int j = 2; j < COLUMN_COUNT; j++)
  304.                         _s[j, i] = 0.0;
  305.  
  306.                     _s[2, i] = _s[1, i];
  307.                     _s[12, i] = _s[1, i];
  308.                 }
  309.             }
  310.             #endregion
  311.  
  312.             //reportData.s = s;
  313.             //reportData.sg1 = sg1;
  314.             //reportData.sg2 = sg2;
  315.             //reportData.Year = forestResourcesReportParams.Year;
  316.             //reportData.ReportName = forestResourcesReportParams.Name;
  317.             return null;
  318.         }
  319.        
  320.  
  321.         public override void CreateDocument(object obj, string formatKey, Procedure<int> progressCallback, string templateFolder, System.IO.Stream outputStream)
  322.         {
  323. #if DEBUG_LOG
  324.             Program.LogSystem.Info("F15_begin_createDoc");
  325. #endif
  326.             #region Создание документа
  327.             //Form1ReportData rd = (Form1ReportData)obj;
  328.             int progress_counter = 0;
  329.             int progress = 0;
  330.             double progress_q = 0.0;
  331.             //ForestResourcesReportParams forestResourcesReportParams = reportParams as ForestResourcesReportParams;
  332.  
  333.             //templateFolder += _description.Key + "\\" + formatKey + "\\";
  334.             TemplateProcessor tprocessor = new TemplateProcessor();
  335.             Dictionary<int, string> results = new Dictionary<int, string>();
  336.             DateTime creationDateTime = DateTime.Now;
  337.             int MAX_ROW_COUNT = formatKey == Program.HTML_FORMAT_KEY ? 100 : 14;
  338.  
  339.             bool nbspFlag = formatKey == Program.HTML_FORMAT_KEY;
  340.             //string emptyValue = formatKey == Program.HTML_FORMAT_KEY ? "&nbsp;" : String.Empty;
  341.  
  342.             #region Параметры шаблонов
  343.             tprocessor.Parameters.Add(new TemplateParameter2("R_PROPERTY", tprocessor.ReadFile(templateFolder + "rproperty.tpl")));
  344.             tprocessor.Parameters.Add(new TemplateParameter2("PAGE_BREAK", tprocessor.ProcessFile(templateFolder + "pagebreak.tpl")));
  345.             tprocessor.Parameters.Add(new TemplateParameter2("DOCUMENT_CREATION_DATETIME", String.Format("{0}-{1:D2}-{2:D2}T{3:D2}:{4:D2}:{5:D2}Z", creationDateTime.Year, creationDateTime.Month, creationDateTime.Day, creationDateTime.Hour, creationDateTime.Minute, creationDateTime.Second)));
  346.             tprocessor.Parameters.Add(new TemplateParameter2("ACTUALIZATION_DATE", String.Format("01.01.{0}", _reportParams.SelectOptions.YearOfActualization)));
  347.             tprocessor.Parameters.Add(new TemplateParameter2("DOCUMENT_CREATION_DATE", creationDateTime.ToShortDateString()));
  348.             tprocessor.Parameters.Add(new TemplateParameter2("SHEET_NUMBER"));
  349.             tprocessor.Parameters.Add(new TemplateParameter2("RELIEF_TYPE"));
  350.             tprocessor.Parameters.Add(new TemplateParameter2("ROWS_CONTENT"));
  351.             tprocessor.Parameters.Add(new TemplateParameter2("BODY_CONTENT"));
  352.  
  353.             for (int i = 1; i <= 24; i++)
  354.                 tprocessor.Parameters.Add(new NumericTemplateParameter2("VALUE_S" + i.ToString(), 0, nbspFlag, (byte)2, DecimalSeparator.Comma));
  355.  
  356.             // Для параметров, которые могут содержать спецсимволы.
  357.             tprocessor.Parameters.Add(new HtmlEncodedTemplateParameter2("REPORT_NAME", _reportParams.Name, nbspFlag));
  358.             tprocessor.Parameters.Add(new HtmlEncodedTemplateParameter2("VALUE_A", null, nbspFlag));
  359.             tprocessor.Parameters.Add(new HtmlEncodedTemplateParameter2("VALUE_B", null, nbspFlag));
  360.             #endregion
  361.  
  362.             string row_template_1 = tprocessor.ReadFile(templateFolder + "rowcontent_1.tpl");
  363.             string row_template_2 = tprocessor.ReadFile(templateFolder + "rowcontent_2.tpl");
  364.             string header_template_1 = tprocessor.ReadFile(templateFolder + "header_1.tpl");
  365.             string header_template_2 = tprocessor.ReadFile(templateFolder + "header_2.tpl");
  366.  
  367.             tprocessor.Parameters["RELIEF_TYPE"].Value = _sg1 > _sg2 ? "горный" : "равнинный";
  368.  
  369.             progress_q = 2.0 / _form1RowsList.Count;
  370.  
  371.             // На первой итерации формируем результаты со строками №№1-12
  372.             // На второй - результаты со строками №№13-24
  373.             for (int iteration = 1; iteration <= 2; iteration++)
  374.             {
  375.  
  376.                 #region Переменные
  377.  
  378.                 bool nextResult = true;
  379.                 string rowsTemplate = String.Empty;
  380.  
  381.                 int resultId = 0;
  382.                 int rc = 0; // Количество созданных строк данных
  383.                 int result_count = 0;
  384.  
  385.                 //progress_counter = 0;
  386.                 #endregion
  387.  
  388.                 // Перебор всех строк формы учета
  389.                 for (int rowIndex = 0; rowIndex < _form1RowsList.Count; rowIndex++)
  390.                 {
  391.                     #region Callback
  392.                     progress_counter++;
  393.                     if (formatKey == Program.HTML_FORMAT_KEY)
  394.                     {
  395.                         progress = 95 + 2 * (iteration - 1) + (int)(progress_q * progress_counter);
  396.                     }
  397.                     else
  398.                     {
  399.                         progress = 90 + 2 * (iteration - 1) + (int)(progress_q * progress_counter);
  400.                     }
  401.                     progressCallback(progress);
  402.                     #endregion
  403.  
  404.                     // Пропуск строк с общей площадью, равной нулю.
  405.                     if (_s[1, rowIndex] == 0.0)
  406.                         continue;
  407.  
  408.                     if (nextResult)
  409.                     {
  410.                         nextResult = false;
  411.                         result_count++;
  412.                         rc = 0;
  413.  
  414.                         switch (iteration)
  415.                         {
  416.                             case 1:
  417.                                 resultId = 2 * result_count - 1;
  418.                                 rowsTemplate = row_template_1;
  419.                                 break;
  420.                             case 2:
  421.                                 resultId = 2 * result_count;
  422.                                 rowsTemplate = row_template_2;
  423.                                 break;
  424.                         }
  425.                         results.Add(resultId, String.Empty);
  426.                     }
  427.                     tprocessor.Parameters["VALUE_A"].Value = _form1RowsList[rowIndex].Name;
  428.                     tprocessor.Parameters["VALUE_B"].Value = _form1RowsList[rowIndex].External_ID;
  429.  
  430.                     for (int k = 1; k <= 12; k++)
  431.                     {
  432.                         int k0 = (iteration - 1) * 12 + k;
  433.                         if (_s[k0, rowIndex] == 0.0) tprocessor.Parameters["VALUE_S" + k0.ToString()].Value = null;
  434.                         else tprocessor.Parameters["VALUE_S" + k0.ToString()].Value = _s[k0, rowIndex];
  435.                         //tprocessor.Parameters["VALUE_S" + k0.ToString()].Value = rd.s[k0, rowIndex] == 0.0 ? null : rd.s[k0, rowIndex];
  436.                     }
  437.  
  438.                     results[resultId] += tprocessor.ProcessString(rowsTemplate);
  439.                     rc++;
  440.  
  441.                     // Если достигнуто предельное количество строк данных, то создаем новый результирующий набор
  442.                     if (rc == MAX_ROW_COUNT)
  443.                     {
  444.                         nextResult = true;
  445.                     }
  446.                 }
  447.             } // iteration
  448.  
  449.             int[] keys = new int[results.Keys.Count];
  450.             results.Keys.CopyTo(keys, 0);
  451.  
  452.             Array.Sort(keys);
  453.             for (int i = 0; i < keys.Length; i++)
  454.             {
  455.                 decimal d;
  456.                 string headerTemplateFile = String.Empty;
  457.                 if (keys[i] % 2 == 0)
  458.                 {
  459.                     headerTemplateFile = header_template_2;
  460.  
  461.                     // В конец каждого второго кроме последнего ставим разрыв страницы.
  462.                     if (i != keys.Length - 1)
  463.                         //results[keys[i]] += vars["PAGE_BREAK"];
  464.                         results[keys[i]] += tprocessor.Parameters["PAGE_BREAK"].Value;
  465.  
  466.                     d = keys[i] / 2;
  467.                 }
  468.                 else
  469.                 {
  470.                     headerTemplateFile = header_template_1;
  471.                     d = (keys[i] + 1) / 2;
  472.                 }
  473.                 tprocessor.Parameters["SHEET_NUMBER"].Value = Convert.ToString(Math.Floor(d));
  474.  
  475.                
  476.                 tprocessor.Parameters["ROWS_CONTENT"].Value = results[keys[i]];
  477.                 tprocessor.Parameters["BODY_CONTENT"].Value += tprocessor.ProcessString(headerTemplateFile);
  478.             }
  479.             tprocessor.ProcessFileToStream(outputStream, templateFolder + "document.tpl");
  480.             //tprocessor.ProcessStringToStream(
  481.             #endregion
  482.         }
  483.     }
  484. }
  485.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement