/// <summary> /// Вставка новой ячейки /// </summary> /// <param name="node"></param> /// <param name="aCellIndex"></param> /// <param name="value"></param> //private void InsertCell(XmlNode node, bool isParent, int aCellIndex, object value, string type) private void InsertCell(XmlNode node, bool isParent, NamedRange obj, object value) { XmlNode xnCell = _doc.CreateElement("Cell"); XmlAttribute attCell = _doc.CreateAttribute("Index", "urn:schemas-microsoft-com:office:spreadsheet"); //attCell.Value = aCellIndex.ToString(); attCell.Value = obj.pColumnIndex.ToString(); xnCell.Attributes.Append(attCell); if (obj.pStyleId.Length > 0) { attCell = _doc.CreateAttribute("StyleID", "urn:schemas-microsoft-com:office:spreadsheet"); attCell.Value = obj.pStyleId; xnCell.Attributes.Append(attCell); } attCell = _doc.CreateAttribute("Imported", "urn:schemas-microsoft-com:office:spreadsheet"); //attCell.Value = "True"; xnCell.Attributes.Append(attCell); XmlNode xnData = _doc.CreateElement("Data"); //if (obj.pType.ToLower().Equals("number")) // value = value.ToString().Replace(",", "."); string val = ReplaceDotByComma(obj.pType, value.ToString()); xnData.InnerText = val; XmlAttribute attData = _doc.CreateAttribute("Type", "urn:schemas-microsoft-com:office:spreadsheet"); //attData.Value = type; string type = string.Empty; switch (obj.pType) { case "number": type = "Number"; break; case "string": type = "String"; break; default: type = "String"; break; } attData.Value = type; xnData.Attributes.Append(attData); xnCell.AppendChild(xnData); if (isParent) node.AppendChild(xnCell); else node.ParentNode.InsertAfter(xnCell, node); }
/// <summary> /// обработка шаблона /// </summary> public string TemplateProcess() { _al = new ArrayList(); //string s = DateTime.Now.ToShortDateString(); //string outFN = string.Format("{0}_{1}.xml", tempName, s); //outFN = pTempPath + outFN; try { //_tempName = tempName; //_doc = new XmlDocument(); //_doc.Load(tempPath); NameTable nt = new NameTable(); // Создаем менеджер неймспейсов XmlNamespaceManager nsmgr = new XmlNamespaceManager(nt); nsmgr.AddNamespace("", "urn:schemas-microsoft-com:office:spreadsheet"); nsmgr.AddNamespace("o", "urn:schemas-microsoft-com:office:office"); nsmgr.AddNamespace("x", "urn:schemas-microsoft-com:office:excel"); nsmgr.AddNamespace("ss", "urn:schemas-microsoft-com:office:spreadsheet"); nsmgr.AddNamespace("html", "http://www.w3.org/TR/REC-html40"); // Добавляем свой неймспейс XPathNavigator nav = _doc.CreateNavigator(); XPathNavigator node = nav.SelectSingleNode("//Names"); //, nsmgr); #region Набираем массив данных значениями поименованных ячеек // Вставлять нужно, сортируя по номеру строки, ячейки node.MoveToFirstChild(); do { NamedRange nr = new NamedRange(); nr.pName = node.GetAttribute("Name", "urn:schemas-microsoft-com:office:spreadsheet"); //ss:RefersTo="=Лист1!R5C3" string str = node.GetAttribute("RefersTo", "urn:schemas-microsoft-com:office:spreadsheet"); int indexR = str.IndexOf("R"); int indexC = str.IndexOf("C"); int rIndex = Convert.ToInt16(str.Substring(indexR + 1, (indexC - indexR - 1))); nr.pRowIndex = rIndex; nr.pNewRowIndex = rIndex; nr.pColumnIndex = Convert.ToInt16(str.Substring(indexC + 1)); if (!(node.GetAttribute("direction", string.Empty).Length == 0)) nr.pDirection = (Direction)Enum.Parse(typeof(Direction), node.GetAttribute("direction", string.Empty)); if (!(node.GetAttribute("included", string.Empty).Length == 0)) nr.pIncluded = Convert.ToBoolean(node.GetAttribute("included", string.Empty)); if (!(node.GetAttribute("multiple", string.Empty).Length == 0)) nr.pMultiple = Convert.ToBoolean(node.GetAttribute("multiple", string.Empty)); if (!(node.GetAttribute("table", string.Empty).Length == 0)) nr.pTableIndex = Convert.ToInt16(node.GetAttribute("table", string.Empty)); if (!(node.GetAttribute("field", string.Empty).Length == 0)) nr.pField = node.GetAttribute("field", string.Empty); if (!(node.GetAttribute("type", string.Empty).Length == 0)) nr.pType = node.GetAttribute("type", string.Empty).ToLower(); if (!(node.GetAttribute("empty", string.Empty).Length == 0)) nr.pIsEmpty = Convert.ToBoolean(node.GetAttribute("empty", string.Empty)); if (!(node.GetAttribute("styleInhereted", string.Empty).Length == 0)) nr.pStyleInhereted = Convert.ToBoolean(node.GetAttribute("styleInhereted", string.Empty)); // сортировка сначала по строке, потом по колонке int i = 0; while (true) { if (_al.Count <= i) break; if (((NamedRange)_al[i]).pRowIndex > nr.pRowIndex || (((NamedRange)_al[i]).pRowIndex == nr.pRowIndex && ((NamedRange)_al[i]).pColumnIndex > nr.pColumnIndex)) break; i++; } _al.Insert(i, nr); } while (node.MoveToNext()); // наследование стилей для строк таблицы InheritStyle(nsmgr); #endregion #region Заполнение шаблона из массива данных for (int i = 0; i < _al.Count; i++) { NamedRange obj = _al[i] as NamedRange; if (obj.pIsEmpty) continue; // если значения нет, то никаких действий. Это в случае, когда больше одной таблицы, и нужная таблица пустая try { string temp = _ds.Tables[obj.pTableIndex].Rows[0][obj.pField].ToString(); } catch { continue; } //if (_ds.Tables[obj.pTableIndex].Rows[0][obj.pField] == null) switch ((int)obj.pDirection) { // внутри case 0: { #region Inside bool Exists = false; bool isParent = true; XmlNode curNode = FindRowByIndex(nsmgr, obj.pNewRowIndex, out Exists, out isParent); //obj.pName, bool toUpdate; // менять или не менять ссылку на поименованные ячейки XmlNode newRowNode = curNode; if (!Exists) newRowNode = InsertRow(nsmgr, obj.pName, curNode, obj.pNewRowIndex, out toUpdate); isParent = true; XmlNode previousNode = null; // либо левый сосед, либо предок (если нет соседа) if (Exists) previousNode = FindCellByIndex(nsmgr, newRowNode, obj.pColumnIndex, out Exists, out isParent); else previousNode = newRowNode; if (!Exists) //InsertCell(previousNode, isParent, obj.pColumnIndex, // _ds.Tables[obj.pTableIndex].Rows[0][obj.pField], obj.pType); InsertCell(previousNode, isParent, obj, _ds.Tables[obj.pTableIndex].Rows[0][obj.pField]); else { UpdateExistingCell(previousNode, _ds.Tables[obj.pTableIndex].Rows[0][obj.pField].ToString(), obj.pType); //previousNode.FirstChild.InnerText = _ds.Tables[obj.pTableIndex].Rows[0][obj.pField].ToString(); } break; #endregion } // вверх case 1: break; // вниз case 2: { #region Down // вставка строки int newRows = 0; if (obj.pMultiple) { bool Exists = false; bool isParent = true; // когда вниз, то такая строка ДОЛЖНА уже быть! XmlNode curNode = FindRowByIndex(nsmgr, obj.pRowIndex, out Exists, out isParent); //obj.pName, XmlNode newRowNode = null; foreach (DataRow dr in _ds.Tables[obj.pTableIndex].Rows) { newRows++; if (!(newRowNode == null)) curNode = newRowNode; bool toUpdate; // менять или не менять ссылку на поименованные ячейки newRowNode = InsertRow(nsmgr, obj.pName, curNode, obj.pRowIndex + newRows, out toUpdate); isParent = true; if (toUpdate) UpdateNamedRangeRowIndex(obj.pRowIndex + newRows); //InsertCell(newRowNode, isParent, obj.pColumnIndex, dr[obj.pField], obj.pType); InsertCell(newRowNode, isParent, obj, dr[obj.pField]); } } else { // если значение == '', то писать не нужно if (_ds.Tables[obj.pTableIndex].Rows[0][obj.pField].ToString().Length != 0) { bool Exists = false; bool isParent = true; XmlNode curNode = FindRowByIndex(nsmgr, obj.pRowIndex, out Exists, out isParent); //obj.pName, bool toUpdate; XmlNode newRowNode = InsertRow(nsmgr, obj.pName, curNode, obj.pRowIndex + 1, out toUpdate); //curNode, isParent = true; if (toUpdate) UpdateNamedRangeRowIndex(obj.pRowIndex + 1); //InsertCell(newRowNode, isParent, obj.pColumnIndex, // _ds.Tables[obj.pTableIndex].Rows[0][obj.pField], obj.pType); InsertCell(newRowNode, isParent, obj, _ds.Tables[obj.pTableIndex].Rows[0][obj.pField]); //XmlNode previousNode = null; // либо левый сосед, либо предок (если нет соседа) //if (Exists) // previousNode = FindCellByIndex(nsmgr, newRowNode, obj.pColumnIndex, out Exists, out isParent); //else // previousNode = newRowNode; //InsertCell(previousNode, isParent, obj.pColumnIndex, _ds.Tables[obj.pTableIndex].Rows[0][obj.pField]); } } //IncreaseRowIndex(nsmgr, nList, obj.pRowIndex + 1, newRows); ModifyNRReference(nsmgr, obj.pName, obj.pRowIndex, newRows); //, obj.pColumnIndex //i = _al.Count; // чтобы выйти из цикла break; #endregion } // вправо case 3: { #region Right // строка ДОЛЖНА существовать! bool Exists = false; bool isParent = true; XmlNode curNode = FindRowByIndex(nsmgr, obj.pNewRowIndex, out Exists, out isParent); //obj.pName, XmlNode previousNode = null; // либо левый сосед, либо предок (если нет соседа) previousNode = FindCellByIndex(nsmgr, curNode, obj.pColumnIndex, out Exists, out isParent); if (!Exists) //InsertCell(previousNode, isParent, obj.pColumnIndex, // _ds.Tables[obj.pTableIndex].Rows[0][obj.pField], obj.pType); InsertCell(previousNode, isParent, obj, _ds.Tables[obj.pTableIndex].Rows[0][obj.pField]); else { string val = ReplaceDotByComma(obj.pType, _ds.Tables[obj.pTableIndex].Rows[0][obj.pField].ToString()); //previousNode.FirstChild.InnerText = _ds.Tables[obj.pTableIndex].Rows[0][obj.pField].ToString(); previousNode.FirstChild.InnerText = val; } //InsertCell(curNode, false, obj.pColumnIndex, // _ds.Tables[obj.pTableIndex].Rows[0][obj.pField], obj.pType); break; #endregion } // влево case 4: break; default: break; } } #endregion //XmlWriterSettings xws = new XmlWriterSettings(); //xws.ConformanceLevel = ConformanceLevel.Document; //xw = XmlWriter.Create(outFN, xws); //xw.WriteNode(nav, true); //XmlAttribute att = node. (string.Empty, "xmlns", "urn:schemas-microsoft-com:office:spreadsheet", "urn:schemas-microsoft-com:office:spreadsheet"); //doc.Attributes.InsertBefore(att); // добавляем наймспэйс по умолчанию, который почему-то не записывается в результирующий файл // xmlns="urn:schemas-microsoft-com:office:spreadsheet" IncreaseExpandedRowCount(nsmgr); // такой вариант НЕ прокатывает (( //XmlAttribute att = _doc.CreateAttribute(string.Empty, "xmlns", "urn:schemas-microsoft-com:office:spreadsheet"); //XmlNode mainNode = _doc.SelectSingleNode("Workbook"); //mainNode.Attributes.Prepend(att); node = nav.SelectSingleNode("//Workbook"); node.CreateAttribute(string.Empty, @"xmlns", "", "urn:schemas-microsoft-com:office:spreadsheet"); //XPathNavigator fstAtt = node.Clone(); //fstAtt.MoveToFirstAttribute(); //fstAtt.InsertBefore("xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\""); return _doc.InnerXml; /* _doc.Save(outFN); //System.Windows.Forms.MessageBox.Show("Шаблон успешно заполнен"); Process prc = new Process(); ProcessStartInfo psi = new ProcessStartInfo("Excel", outFN); prc.StartInfo = psi; prc.Start(); */ } catch (XmlException ex) { throw new XmlException(ex.Message); //return @"Cannot load file\n" + ex.Message; } catch (System.ArgumentException ex) { throw new System.ArgumentException(ex.Message); //return @"Cannot find single node\n" + ex.Message; } catch (System.Xml.XPath.XPathException ex) { throw new System.Xml.XPath.XPathException(ex.Message); //return @"Cannot find path\n" + ex.Message; } catch (Exception ex) { throw new Exception(ex.Message); //return ex.Message; } }