/// <summary> /// Returns true if the node passed is set as hidden, returns false if it is visible. /// </summary> private bool isHidden(Aspose.Words.Node node) { if (node is Aspose.Words.Inline) { // If the node is Inline then cast it to retrieve the Font property which contains the hidden property Aspose.Words.Inline currentNode = (Aspose.Words.Inline)node; return(currentNode.Font.Hidden); } else if (node.NodeType == NodeType.Paragraph) { // If the node is a paragraph cast it to retrieve the ParagraphBreakFont which contains the hidden property Paragraph para = (Paragraph)node; return(para.ParagraphBreakFont.Hidden); } else if (node is ShapeBase) { // Node is a shape or groupshape. ShapeBase shape = (ShapeBase)node; return(shape.Font.Hidden); } else if (node is InlineStory) { // Node is a comment or footnote. InlineStory inlineStory = (InlineStory)node; return(inlineStory.Font.Hidden); } // A node that is passed to this method which does not contain a hidden property will end up here. // By default nodes are not hidden so return false. return(false); }
public void RemoveNodes() { Aspose.Words.Document doc = new Aspose.Words.Document(); //ExStart //ExFor:Node //ExFor:Node.NodeType //ExFor:Node.Remove //ExSummary:Shows how to remove all nodes of a specific type from a composite node. In this example we remove tables from a section body. // Get the section that we want to work on. Aspose.Words.Section section = doc.Sections[0]; Body body = section.Body; // Select the first child node in the body. Aspose.Words.Node curNode = body.FirstChild; while (curNode != null) { // Save the pointer to the next sibling node because if the current // node is removed from the parent in the next step, we will have // no way of finding the next node to continue the loop. Aspose.Words.Node nextNode = curNode.NextSibling; // A section body can contain Paragraph and Table nodes. // If the node is a Table, remove it from the parent. if (curNode.NodeType.Equals(NodeType.Table)) { curNode.Remove(); } // Continue going through child nodes until null (no more siblings) is reached. curNode = nextNode; } //ExEnd }
public void IndexChildNodes() { Aspose.Words.Document doc = new Aspose.Words.Document(); Paragraph paragraph = (Paragraph)doc.GetChild(NodeType.Paragraph, 0, true); //ExStart //ExFor:NodeCollection.Count //ExFor:NodeCollection.Item //ExId:ChildNodesIndexer //ExSummary:Shows how to enumerate immediate children of a CompositeNode using indexed access. NodeCollection children = paragraph.ChildNodes; for (int i = 0; i < children.Count; i++) { Aspose.Words.Node child = children[i]; // Paragraph may contain children of various types such as runs, shapes and so on. if (child.NodeType.Equals(NodeType.Run)) { // Say we found the node that we want, do something useful. Run run = (Run)child; Console.WriteLine(run.Text); } } //ExEnd }
public void DeleteAllImagesPreOrder() { Aspose.Words.Document doc = new Aspose.Words.Document(MyDir + "Image.SampleImages.doc"); Assert.AreEqual(6, doc.GetChildNodes(NodeType.Shape, true).Count); //ExStart //ExFor:Node.NextPreOrder //ExSummary:Shows how to delete all images from a document using pre-order tree traversal. Aspose.Words.Node curNode = doc; while (curNode != null) { Aspose.Words.Node nextNode = curNode.NextPreOrder(doc); if (curNode.NodeType.Equals(NodeType.Shape)) { Shape shape = (Shape)curNode; // Several shape types can have an image including image shapes and OLE objects. if (shape.HasImage) { shape.Remove(); } } curNode = nextNode; } //ExEnd Assert.AreEqual(1, doc.GetChildNodes(NodeType.Shape, true).Count); doc.Save(MyDir + "Image.DeleteAllImagesPreOrder Out.doc"); }
/// <summary> /// Goes through siblings starting from the start node until it finds a node of the specified type or null. /// </summary> private static Aspose.Words.Node FindNextSibling(Aspose.Words.Node startNode, NodeType nodeType) { for (Aspose.Words.Node node = startNode; node != null; node = node.NextSibling) { if (node.NodeType.Equals(nodeType)) { return(node); } } return(null); }
public static void GetParentNode() { //ExStart:GetParentNode // Create a new empty document. It has one section. Document doc = new Document(); // The section is the first child node of the document. Aspose.Words.Node section = doc.FirstChild; // The section's parent node is the document. Console.WriteLine("Section parent is the document: " + (doc == section.ParentNode)); //ExEnd:GetParentNode }
/// <summary> /// Removes nodes from start up to but not including the end node. /// Start and end are assumed to have the same parent. /// </summary> private static void RemoveSameParent(Aspose.Words.Node startNode, Aspose.Words.Node endNode) { if ((endNode != null) && (startNode.ParentNode != endNode.ParentNode)) { throw new ArgumentException("Start and end nodes are expected to have the same parent."); } Aspose.Words.Node curChild = startNode; while ((curChild != null) && (curChild != endNode)) { Aspose.Words.Node nextChild = curChild.NextSibling; curChild.Remove(); curChild = nextChild; } }
/// <summary> /// A simple function that will walk through all children of a specified node recursively /// and print the type of each node to the screen. /// </summary> public static void TraverseAllNodes(CompositeNode parentNode) { // This is the most efficient way to loop through immediate children of a node. for (Aspose.Words.Node childNode = parentNode.FirstChild; childNode != null; childNode = childNode.NextSibling) { // Do some useful work. Console.WriteLine(Aspose.Words.Node.NodeTypeToString(childNode.NodeType)); // Recurse into the node if it is a composite node. if (childNode.IsComposite) { TraverseAllNodes((CompositeNode)childNode); } } }
/// <summary> /// Retrieves text from start up to but not including the end node. /// </summary> private static string GetTextSameParent(Aspose.Words.Node startNode, Aspose.Words.Node endNode) { if ((endNode != null) && (startNode.ParentNode != endNode.ParentNode)) { throw new ArgumentException("Start and end nodes are expected to have the same parent."); } StringBuilder builder = new StringBuilder(); for (Aspose.Words.Node child = startNode; !child.Equals(endNode); child = child.NextSibling) { builder.Append(child.GetText()); } return(builder.ToString()); }
public void GetNodeTypeEnums() { //ExStart //ExFor:Paragraph.NodeType //ExFor:Table.NodeType //ExFor:Node.NodeType //ExFor:Footnote.NodeType //ExFor:FormField.NodeType //ExFor:SmartTag.NodeType //ExFor:Cell.NodeType //ExFor:Row.NodeType //ExFor:Document.NodeType //ExFor:Comment.NodeType //ExFor:Run.NodeType //ExFor:Section.NodeType //ExFor:SpecialChar.NodeType //ExFor:Shape.NodeType //ExFor:FieldEnd.NodeType //ExFor:FieldSeparator.NodeType //ExFor:FieldStart.NodeType //ExFor:BookmarkStart.NodeType //ExFor:CommentRangeEnd.NodeType //ExFor:BuildingBlock.NodeType //ExFor:GlossaryDocument.NodeType //ExFor:BookmarkEnd.NodeType //ExFor:GroupShape.NodeType //ExFor:CommentRangeStart.NodeType //ExId:GetNodeTypeEnums //ExSummary:Shows how to retrieve the NodeType enumeration of nodes. Aspose.Words.Document doc = new Aspose.Words.Document(MyDir + "Document.doc"); // Let's pick a node that we can't be quite sure of what type it is. // In this case lets pick the first node of the first paragraph in the body of the document Aspose.Words.Node node = doc.FirstSection.Body.FirstParagraph.FirstChild; Console.WriteLine("NodeType of first child: " + Aspose.Words.Node.NodeTypeToString(node.NodeType)); // This time let's pick a node that we know the type of. Create a new paragraph and a table node. Paragraph para = new Paragraph(doc); Table table = new Table(doc); // Access to NodeType for typed nodes will always return their specific NodeType. // i.e A paragraph node will always return NodeType.Paragraph, a table node will always return NodeType.Table. Console.WriteLine("NodeType of Paragraph: " + Aspose.Words.Node.NodeTypeToString(para.NodeType)); Console.WriteLine("NodeType of Table: " + Aspose.Words.Node.NodeTypeToString(table.NodeType)); //ExEnd }
public void GetParentNode() { //ExStart //ExFor:Node.ParentNode //ExId:AccessParentNode //ExSummary:Shows how to access the parent node. // Create a new empty document. It has one section. Aspose.Words.Document doc = new Aspose.Words.Document(); // The section is the first child node of the document. Aspose.Words.Node section = doc.FirstChild; // The section's parent node is the document. Console.WriteLine("Section parent is the document: " + (doc == section.ParentNode)); //ExEnd Assert.AreEqual(doc, section.ParentNode); }
public void CompositeNode_SelectNodes() { //ExStart //ExFor:CompositeNode.SelectSingleNode //ExFor:CompositeNode.SelectNodes //ExSummary:Shows how to select certain nodes by using an XPath expression. Aspose.Words.Document doc = new Aspose.Words.Document(MyDir + "Table.Document.doc"); // This expression will extract all paragraph nodes which are descendants of any table node in the document. // This will return any paragraphs which are in a table. NodeList nodeList = doc.SelectNodes("//Table//Paragraph"); // This expression will select any paragraphs that are direct children of any body node in the document. nodeList = doc.SelectNodes("//Body/Paragraph"); // Use SelectSingleNode to select the first result of the same expression as above. Aspose.Words.Node node = doc.SelectSingleNode("//Body/Paragraph"); //ExEnd }
/// <summary> /// Calculates what level a table is nested inside other tables. /// <returns> /// An integer containing the level the table is nested at. /// 0 = Table is not nested inside any other table /// 1 = Table is nested within one parent table /// 2 = Table is nested within two parent tables etc..</returns> /// </summary> private static int GetNestedDepthOfTable(Table table) { int depth = 0; NodeType type = table.NodeType; // The parent of the table will be a Cell, instead attempt to find a grandparent that is of type Table Aspose.Words.Node parent = table.GetAncestor(type); while (parent != null) { // Every time we find a table a level up we increase the depth counter and then try to find an // ancestor of type table from the parent. depth++; parent = parent.GetAncestor(type); } return(depth); }
public static void IndexChildNodes() { //ExStart:IndexChildNodes Document doc = new Document(); Paragraph paragraph = (Paragraph)doc.GetChild(NodeType.Paragraph, 0, true); NodeCollection children = paragraph.ChildNodes; for (int i = 0; i < children.Count; i++) { Aspose.Words.Node child = children[i]; // Paragraph may contain children of various types such as runs, shapes and so on. if (child.NodeType.Equals(NodeType.Run)) { // Say we found the node that we want, do something useful. Run run = (Run)child; Console.WriteLine(run.Text); } } //ExEnd:IndexChildNodes }
public void ConvertNodeToHtmlWithDefaultOptions() { //ExStart //ExFor:Node.ToString(SaveFormat) //ExSummary:Exports the content of a node to string in HTML format using default options. Aspose.Words.Document doc = new Aspose.Words.Document(MyDir + "Document.doc"); // Extract the last paragraph in the document to convert to HTML. Aspose.Words.Node node = doc.LastSection.Body.LastParagraph; // When ToString is called using the SaveFormat overload then conversion is executed using default save options. // When saving to HTML using default options the following settings are set: // ExportImagesAsBase64 = true // CssStyleSheetType = CssStyleSheetType.Inline // ExportFontResources = false string nodeAsHtml = node.ToString(SaveFormat.Html); //ExEnd Assert.AreEqual("<p style=\"margin:0pt\"><span style=\"font-family:'Times New Roman'; font-size:12pt\">Hello World!</span></p>", nodeAsHtml); }
//ExStart //ExFor:Paragraph.IsEndOfSection //ExId:InsertDocumentMain //ExSummary:This is a method that inserts contents of one document at a specified location in another document. /// <summary> /// Inserts content of the external document after the specified node. /// Section breaks and section formatting of the inserted document are ignored. /// </summary> /// <param name="insertAfterNode">Node in the destination document after which the content /// should be inserted. This node should be a block level node (paragraph or table).</param> /// <param name="srcDoc">The document to insert.</param> static void InsertDocument(Aspose.Words.Node insertAfterNode, Aspose.Words.Document srcDoc) { // Make sure that the node is either a paragraph or table. if ((!insertAfterNode.NodeType.Equals(NodeType.Paragraph)) & (!insertAfterNode.NodeType.Equals(NodeType.Table))) { throw new ArgumentException("The destination node should be either a paragraph or table."); } // We will be inserting into the parent of the destination paragraph. CompositeNode dstStory = insertAfterNode.ParentNode; // This object will be translating styles and lists during the import. NodeImporter importer = new NodeImporter(srcDoc, insertAfterNode.Document, ImportFormatMode.KeepSourceFormatting); // Loop through all sections in the source document. foreach (Aspose.Words.Section srcSection in srcDoc.Sections) { // Loop through all block level nodes (paragraphs and tables) in the body of the section. foreach (Aspose.Words.Node srcNode in srcSection.Body) { // Let's skip the node if it is a last empty paragraph in a section. if (srcNode.NodeType.Equals(NodeType.Paragraph)) { Paragraph para = (Paragraph)srcNode; if (para.IsEndOfSection && !para.HasChildNodes) { continue; } } // This creates a clone of the node, suitable for insertion into the destination document. Aspose.Words.Node newNode = importer.ImportNode(srcNode, true); // Insert new node after the reference node. dstStory.InsertAfter(newNode, insertAfterNode); insertAfterNode = newNode; } } }
public void EnumNextSibling() { Aspose.Words.Document doc = new Aspose.Words.Document(); //ExStart //ExFor:CompositeNode.FirstChild //ExFor:Node.NextSibling //ExFor:Node.NodeTypeToString //ExFor:Node.NodeType //ExSummary:Shows how to enumerate immediate child nodes of a composite node using NextSibling. In this example we enumerate all paragraphs of a section body. // Get the section that we want to work on. Aspose.Words.Section section = doc.Sections[0]; Body body = section.Body; // Loop starting from the first child until we reach null. for (Aspose.Words.Node node = body.FirstChild; node != null; node = node.NextSibling) { // Output the types of the nodes that we come across. Console.WriteLine(Aspose.Words.Node.NodeTypeToString(node.NodeType)); } //ExEnd }
public void CloneCompositeNode() { //ExStart //ExFor:Node //ExFor:Node.Clone //ExSummary:Shows how to clone composite nodes with and without their child nodes. // Create a new empty document. Aspose.Words.Document doc = new Aspose.Words.Document(); // Add some text to the first paragraph Paragraph para = doc.FirstSection.Body.FirstParagraph; para.AppendChild(new Run(doc, "Some text")); // Clone the paragraph and the child nodes. Aspose.Words.Node cloneWithChildren = para.Clone(true); // Only clone the paragraph and no child nodes. Aspose.Words.Node cloneWithoutChildren = para.Clone(false); //ExEnd Assert.IsTrue(((CompositeNode)cloneWithChildren).HasChildNodes); Assert.IsFalse(((CompositeNode)cloneWithoutChildren).HasChildNodes); }
public void RemoveChild() { Aspose.Words.Document doc = new Aspose.Words.Document(); //ExStart //ExFor:CompositeNode.LastChild //ExFor:Node.PreviousSibling //ExFor:CompositeNode.RemoveChild //ExSummary:Demonstrates use of methods of Node and CompositeNode to remove a section before the last section in the document. // Document is a CompositeNode and LastChild returns the last child node in the Document node. // Since the Document can contain only Section nodes, the last child is the last section. Aspose.Words.Node lastSection = doc.LastChild; // Each node knows its next and previous sibling nodes. // Previous sibling of a section is a section before the specified section. // If the node is the first child, PreviousSibling will return null. Aspose.Words.Node sectionBeforeLast = lastSection.PreviousSibling; if (sectionBeforeLast != null) { doc.RemoveChild(sectionBeforeLast); } //ExEnd }
public void ConvertNodeToHtmlWithSaveOptions() { //ExStart //ExFor:Node.ToString(SaveOptions) //ExSummary:Exports the content of a node to string in HTML format using custom specified options. Aspose.Words.Document doc = new Aspose.Words.Document(MyDir + "Document.doc"); // Extract the last paragraph in the document to convert to HTML. Aspose.Words.Node node = doc.LastSection.Body.LastParagraph; // Create an instance of HtmlSaveOptions and set a few options. HtmlSaveOptions saveOptions = new HtmlSaveOptions(); saveOptions.ExportHeadersFootersMode = ExportHeadersFootersMode.PerSection; saveOptions.ExportRelativeFontSize = true; // Convert the document to HTML and return as a string. Pass the instance of HtmlSaveOptions to // to use the specified options during the conversion. string nodeAsHtml = node.ToString(saveOptions); //ExEnd Assert.AreEqual("<p style=\"margin:0pt\"><span style=\"font-family:'Times New Roman'\">Hello World!</span></p>", nodeAsHtml); }
internal MergeField(FieldStart fieldStart) { if (fieldStart.Equals(null)) throw new ArgumentNullException("fieldStart"); if (!fieldStart.FieldType.Equals(FieldType.FieldMergeField)) throw new ArgumentException("Field start type must be FieldMergeField."); mFieldStart = fieldStart; // Find the field separator node. mFieldSeparator = FindNextSibling(mFieldStart, NodeType.FieldSeparator); if (mFieldSeparator == null) throw new InvalidOperationException("Cannot find field separator."); // Find the field end node. Normally field end will always be found, but in the example document // there happens to be a paragraph break included in the hyperlink and this puts the field end // in the next paragraph. It will be much more complicated to handle fields which span several // paragraphs correctly, but in this case allowing field end to be null is enough for our purposes. mFieldEnd = FindNextSibling(mFieldSeparator, NodeType.FieldEnd); }
internal Hyperlink(FieldStart fieldStart) { if (fieldStart == null) throw new ArgumentNullException("fieldStart"); if (!fieldStart.FieldType.Equals(FieldType.FieldHyperlink)) throw new ArgumentException("Field start type must be FieldHyperlink."); mFieldStart = fieldStart; // Find the field separator node. mFieldSeparator = FindNextSibling(mFieldStart, NodeType.FieldSeparator); if (mFieldSeparator == null) throw new InvalidOperationException("Cannot find field separator."); // Find the field end node. Normally field end will always be found, but in the example document // there happens to be a paragraph break included in the hyperlink and this puts the field end // in the next paragraph. It will be much more complicated to handle fields which span several // paragraphs correctly, but in this case allowing field end to be null is enough for our purposes. mFieldEnd = FindNextSibling(mFieldSeparator, NodeType.FieldEnd); // Field code looks something like [ HYPERLINK "http:\\www.myurl.com" ], but it can consist of several runs. string fieldCode = GetTextSameParent(mFieldStart.NextSibling, mFieldSeparator); Match match = gRegex.Match(fieldCode.Trim()); mIsLocal = (match.Groups[1].Length > 0); //The link is local if \l is present in the field code. mTarget = match.Groups[2].Value; }
/// <summary> /// Converts a textbox to a table by copying the same content and formatting. /// Currently export to HTML will render the textbox as an image which looses any text functionality. /// This is useful to convert textboxes in order to retain proper text. /// </summary> /// <param name="textbox">The textbox shape to convert to a table</param> private static void ConvertTextboxToTable(Shape textBox) { if (textBox.StoryType != StoryType.Textbox) { throw new ArgumentException("Can only convert a shape of type textbox"); } Aspose.Words.Document doc = (Aspose.Words.Document)textBox.Document; Aspose.Words.Section section = (Aspose.Words.Section)textBox.GetAncestor(NodeType.Section); // Create a table to replace the textbox and transfer the same content and formatting. Table table = new Table(doc); // Ensure that the table contains a row and a cell. table.EnsureMinimum(); // Use fixed column widths. table.AutoFit(AutoFitBehavior.FixedColumnWidths); // A shape is inline level (within a paragraph) where a table can only be block level so insert the table // after the paragraph which contains the shape. Aspose.Words.Node shapeParent = textBox.ParentNode; shapeParent.ParentNode.InsertAfter(table, shapeParent); // If the textbox is not inline then try to match the shape's left position using the table's left indent. if (!textBox.IsInline && textBox.Left < section.PageSetup.PageWidth) { table.LeftIndent = textBox.Left; } // We are only using one cell to replicate a textbox so we can make use of the FirstRow and FirstCell property. // Carry over borders and shading. Row firstRow = table.FirstRow; Cell firstCell = firstRow.FirstCell; firstCell.CellFormat.Borders.Color = textBox.StrokeColor; firstCell.CellFormat.Borders.LineWidth = textBox.StrokeWeight; firstCell.CellFormat.Shading.BackgroundPatternColor = textBox.Fill.Color; // Transfer the same height and width of the textbox to the table. firstRow.RowFormat.HeightRule = HeightRule.Exactly; firstRow.RowFormat.Height = textBox.Height; firstCell.CellFormat.Width = textBox.Width; table.AllowAutoFit = false; // Replicate the textbox's horizontal alignment. TableAlignment horizontalAlignment; switch (textBox.HorizontalAlignment) { case HorizontalAlignment.Left: horizontalAlignment = TableAlignment.Left; break; case HorizontalAlignment.Center: horizontalAlignment = TableAlignment.Center; break; case HorizontalAlignment.Right: horizontalAlignment = TableAlignment.Right; break; default: // Most other options are left by default. horizontalAlignment = TableAlignment.Left; break; } table.Alignment = horizontalAlignment; firstCell.RemoveAllChildren(); // Append all content from the textbox to the new table foreach (Aspose.Words.Node node in textBox.GetChildNodes(NodeType.Any, false).ToArray()) { table.FirstRow.FirstCell.AppendChild(node); } // Remove the empty textbox from the document. textBox.Remove(); }
private void _BGWAbsenceNotification_DoWork(object sender, DoWorkEventArgs e) { #region 取得學生 if (entityName.ToLower() == "student") //學生模式 { SelectedStudents = K12.Data.Student.SelectByIDs(K12.Presentation.NLDPanels.Student.SelectedSource); } else if (entityName.ToLower() == "class") //班級模式 { SelectedStudents = new List <StudentRecord>(); foreach (StudentRecord each in Student.SelectByClassIDs(K12.Presentation.NLDPanels.Class.SelectedSource)) { if (each.Status != StudentRecord.StudentStatus.一般) { continue; } SelectedStudents.Add(each); } } else { throw new NotImplementedException(); } SelectedStudents.Sort(new Comparison <StudentRecord>(CommonMethods.ClassSeatNoComparer)); #endregion string reportName = "缺曠通知單"; #region 快取資料 //超級資訊物件 Dictionary <string, StudentOBJ> StudentSuperOBJ = new Dictionary <string, StudentOBJ>(); //合併列印的資料 Dictionary <string, object> Allmapping = new Dictionary <string, object>(); Dictionary <string, string> ReversionDic = new Dictionary <string, string>(); //所有學生ID List <string> allStudentID = new List <string>(); //學生人數 int currentStudentCount = 1; int totalStudentNumber = 0; #region 取得 Period List List <string> periodList = new List <string>(); Dictionary <string, string> TestPeriodList = new Dictionary <string, string>(); int PeriodX = 1; Dictionary <string, object> mappingAccessory_copy = new Dictionary <string, object>(); foreach (K12.Data.PeriodMappingInfo each in K12.Data.PeriodMapping.SelectAll()) { if (!periodList.Contains(each.Name)) { periodList.Add(each.Name); } if (!TestPeriodList.ContainsKey(each.Name)) //節次<-->類別 { TestPeriodList.Add(each.Name, each.Type); } Allmapping.Add("節次" + PeriodX, each.Name); mappingAccessory_copy.Add("節次" + PeriodX, each.Name); ReversionDic.Add(each.Name, "節次" + PeriodX); PeriodX++; } #endregion #region 取得 Absence List Dictionary <string, string> TestAbsenceList = new Dictionary <string, string>(); //代碼替換(新) foreach (K12.Data.AbsenceMappingInfo each in K12.Data.AbsenceMapping.SelectAll()) { if (!absenceList.ContainsKey(each.Name)) { absenceList.Add(each.Name, each.Abbreviation); } if (!TestAbsenceList.ContainsKey(each.Name)) //縮寫<-->假別 { TestAbsenceList.Add(each.Abbreviation, each.Name); } //Allmapping.Add("類型" + DefinedType + "缺曠" + DefinedAbsence, } #endregion //????使用者所選取的所有假別種類???? List <string> userDefinedAbsenceList = new List <string>(); int DefinedType = 1; foreach (string kind in configkeylist) { int DefinedAbsence = 1; Allmapping.Add("類型" + DefinedType, kind); foreach (string type in config[kind]) { Allmapping.Add("類型" + DefinedType + "缺曠" + DefinedAbsence, type); Allmapping.Add("類型" + DefinedType + "縮寫" + DefinedAbsence, absenceList[type]); DefinedAbsence++; if (!userDefinedAbsenceList.Contains(type)) { userDefinedAbsenceList.Add(type); } } DefinedType++; } #region 取得所有學生ID foreach (StudentRecord aStudent in SelectedStudents) { //建立學生資訊,班級、座號、學號、姓名、導師 string studentID = aStudent.ID; if (!StudentSuperOBJ.ContainsKey(studentID)) { StudentSuperOBJ.Add(studentID, new StudentOBJ()); } //學生ID清單 if (!allStudentID.Contains(studentID)) { allStudentID.Add(studentID); } StudentSuperOBJ[studentID].student = aStudent; StudentSuperOBJ[studentID].TeacherName = aStudent.Class != null ? (aStudent.Class.Teacher != null ? aStudent.Class.Teacher.Name : "") : ""; StudentSuperOBJ[studentID].ClassName = aStudent.Class != null ? aStudent.Class.Name : ""; StudentSuperOBJ[studentID].SeatNo = aStudent.SeatNo.HasValue ? aStudent.SeatNo.Value.ToString() : ""; StudentSuperOBJ[studentID].StudentNumber = aStudent.StudentNumber; StudentSuperOBJ[studentID].ParentCode = ""; } #endregion #region 取得家長代碼 // 因應 2019/11/14 弘文要求新epost 增加家長代碼抓取 string ids = string.Join(",", allStudentID); string sql = "select student.id, student.parent_code, student.student_code, student.seat_no, student.name, class.grade_year, class.class_name from student"; sql += " join class on class.id = student.ref_class_id where student.status in (1,2) and student.id in (" + ids + ") order by class.grade_year,class.display_order,class.class_name,student.seat_no"; DataTable dt_parent_code = queryHelper.Select(sql);; foreach (DataRow row in dt_parent_code.Rows) { if (StudentSuperOBJ.ContainsKey("" + row["id"])) { StudentSuperOBJ["" + row["id"]].ParentCode = "" + row["parent_code"]; } } #endregion #region 取得所有學生缺曠紀錄,日期區間 List <AttendanceRecord> attendanceList = K12.Data.Attendance.SelectByDate(SelectedStudents, obj.StartDate, obj.EndDate); if (attendanceList.Count == 0) { e.Cancel = true; //沒有缺曠資料 } foreach (AttendanceRecord attendance in attendanceList) { if (!allStudentID.Contains(attendance.RefStudentID)) //如果是選取班級的學生 { continue; } string studentID = attendance.RefStudentID; DateTime occurDate = attendance.OccurDate; StudentOBJ studentOBJ = StudentSuperOBJ[studentID]; //取得這個物件 foreach (AttendancePeriod attendancePeriod in attendance.PeriodDetail) { string absenceType = attendancePeriod.AbsenceType; //假別 string periodName = attendancePeriod.Period; //節次 //是否為設定檔節次清單之中 if (!TestPeriodList.ContainsKey(periodName)) { continue; } //是否為使用者選取之假別&類型 if (config.ContainsKey(TestPeriodList[periodName])) { if (config[TestPeriodList[periodName]].Contains(absenceType)) { string PeriodAndAbsence = TestPeriodList[periodName] + "," + absenceType; //區間統計 if (!studentOBJ.studentAbsence.ContainsKey(PeriodAndAbsence)) { studentOBJ.studentAbsence.Add(PeriodAndAbsence, 0); } studentOBJ.studentAbsence[PeriodAndAbsence]++; //明細記錄 if (!studentOBJ.studentAbsenceDetail.ContainsKey(occurDate.ToShortDateString())) { studentOBJ.studentAbsenceDetail.Add(occurDate.ToShortDateString(), new Dictionary <string, string>()); } if (!studentOBJ.studentAbsenceDetail[occurDate.ToShortDateString()].ContainsKey(attendancePeriod.Period)) { studentOBJ.studentAbsenceDetail[occurDate.ToShortDateString()].Add(attendancePeriod.Period, attendancePeriod.AbsenceType); } } } } } #endregion List <string> DelStudent = new List <string>(); //列印的學生 #region 條件1 if (obj.ConditionName != "") //如果不等於空就是要判斷啦 { foreach (string each1 in StudentSuperOBJ.Keys) //取出一個學生 { int AbsenceCount = 0; bool AbsenceBOOL = false; foreach (string each2 in StudentSuperOBJ[each1].studentAbsenceDetail.Keys) //取出一天 { foreach (string each3 in StudentSuperOBJ[each1].studentAbsenceDetail[each2].Keys) //取出一節內容 { string each4 = StudentSuperOBJ[each1].studentAbsenceDetail[each2][each3]; if (TestPeriodList.ContainsKey(each3)) { if (config.ContainsKey(TestPeriodList[each3])) { if (obj.ConditionName == each4) { AbsenceCount++; } if (AbsenceCount >= int.Parse(obj.ConditionNumber)) { AbsenceBOOL = true; if (!DelStudent.Contains(each1)) { DelStudent.Add(each1); //把學生ID記下 } } if (AbsenceBOOL) { break; } } } } if (AbsenceBOOL) { break; } } } } #endregion #region 條件2 if (obj.ConditionName2 != "") //如果等於空就是直接全部印啦!! { foreach (string each1 in StudentSuperOBJ.Keys) //取出一個學生 { int AbsenceCount = 0; bool AbsenceBOOL = false; foreach (string each2 in StudentSuperOBJ[each1].studentAbsenceDetail.Keys) //取出一天 { foreach (string each3 in StudentSuperOBJ[each1].studentAbsenceDetail[each2].Keys) //取出一節內容 { string each4 = StudentSuperOBJ[each1].studentAbsenceDetail[each2][each3]; if (TestPeriodList.ContainsKey(each3)) { if (config.ContainsKey(TestPeriodList[each3])) { if (obj.ConditionName2 == each4) { AbsenceCount++; } if (AbsenceCount >= int.Parse(obj.ConditionNumber2)) { AbsenceBOOL = true; DelStudent.Add(each1); //把學生ID記下 } if (AbsenceBOOL) { break; } } if (AbsenceBOOL) { break; } } } } } } #endregion #region 無條件則全部列印 if (obj.ConditionName == "" && obj.ConditionName2 == "") { foreach (string each1 in StudentSuperOBJ.Keys) //取出一個學生 { if (!DelStudent.Contains(each1)) { DelStudent.Add(each1); } } } #endregion #region 取得所有學生缺曠紀錄,學期累計 foreach (AttendanceRecord attendance in K12.Data.Attendance.SelectBySchoolYearAndSemester(Student.SelectByIDs(allStudentID), int.Parse(School.DefaultSchoolYear), int.Parse(School.DefaultSemester))) { //1(大於),0(等於)-1(小於) if (obj.EndDate.CompareTo(attendance.OccurDate) == -1) { continue; } string studentID = attendance.RefStudentID; DateTime occurDate = attendance.OccurDate; StudentOBJ studentOBJ = StudentSuperOBJ[studentID]; //取得這個物件 foreach (AttendancePeriod attendancePeriod in attendance.PeriodDetail) { string absenceType = attendancePeriod.AbsenceType; //假別 string periodName = attendancePeriod.Period; //節次 if (!TestPeriodList.ContainsKey(periodName)) { continue; } string PeriodAndAbsence = TestPeriodList[periodName] + "," + absenceType; //區間統計 if (!studentOBJ.studentSemesterAbsence.ContainsKey(PeriodAndAbsence)) { studentOBJ.studentSemesterAbsence.Add(PeriodAndAbsence, 0); } studentOBJ.studentSemesterAbsence[PeriodAndAbsence]++; } } #endregion #region 取得學生通訊地址資料 foreach (AddressRecord record in Address.SelectByStudentIDs(allStudentID)) { if (obj.ReceiveAddress == "戶籍地址") { if (!string.IsNullOrEmpty(record.PermanentAddress)) { StudentSuperOBJ[record.RefStudentID].address = record.Permanent.County + record.Permanent.Town + record.Permanent.District + record.Permanent.Area + record.Permanent.Detail; } if (!string.IsNullOrEmpty(record.PermanentZipCode)) { StudentSuperOBJ[record.RefStudentID].ZipCode = record.PermanentZipCode; if (record.PermanentZipCode.Length >= 1) { StudentSuperOBJ[record.RefStudentID].ZipCode1 = record.PermanentZipCode.Substring(0, 1); } if (record.PermanentZipCode.Length >= 2) { StudentSuperOBJ[record.RefStudentID].ZipCode2 = record.PermanentZipCode.Substring(1, 1); } if (record.PermanentZipCode.Length >= 3) { StudentSuperOBJ[record.RefStudentID].ZipCode3 = record.PermanentZipCode.Substring(2, 1); } if (record.PermanentZipCode.Length >= 4) { StudentSuperOBJ[record.RefStudentID].ZipCode4 = record.PermanentZipCode.Substring(3, 1); } if (record.PermanentZipCode.Length >= 5) { StudentSuperOBJ[record.RefStudentID].ZipCode5 = record.PermanentZipCode.Substring(4, 1); } } } else if (obj.ReceiveAddress == "聯絡地址") { if (!string.IsNullOrEmpty(record.MailingAddress)) { StudentSuperOBJ[record.RefStudentID].address = record.Mailing.County + record.Mailing.Town + record.Mailing.District + record.Mailing.Area + record.Mailing.Detail; //再處理 } if (!string.IsNullOrEmpty(record.MailingZipCode)) { StudentSuperOBJ[record.RefStudentID].ZipCode = record.MailingZipCode; if (record.MailingZipCode.Length >= 1) { StudentSuperOBJ[record.RefStudentID].ZipCode1 = record.MailingZipCode.Substring(0, 1); } if (record.MailingZipCode.Length >= 2) { StudentSuperOBJ[record.RefStudentID].ZipCode2 = record.MailingZipCode.Substring(1, 1); } if (record.MailingZipCode.Length >= 3) { StudentSuperOBJ[record.RefStudentID].ZipCode3 = record.MailingZipCode.Substring(2, 1); } if (record.MailingZipCode.Length >= 4) { StudentSuperOBJ[record.RefStudentID].ZipCode4 = record.MailingZipCode.Substring(3, 1); } if (record.MailingZipCode.Length >= 5) { StudentSuperOBJ[record.RefStudentID].ZipCode5 = record.MailingZipCode.Substring(4, 1); } } } else if (obj.ReceiveAddress == "其他地址") { if (!string.IsNullOrEmpty(record.Address1Address)) { StudentSuperOBJ[record.RefStudentID].address = record.Address1.County + record.Address1.Town + record.Address1.District + record.Address1.Area + record.Address1.Detail; //再處理 } if (!string.IsNullOrEmpty(record.Address1ZipCode)) { StudentSuperOBJ[record.RefStudentID].ZipCode = record.Address1ZipCode; if (record.Address1ZipCode.Length >= 1) { StudentSuperOBJ[record.RefStudentID].ZipCode1 = record.Address1ZipCode.Substring(0, 1); } if (record.Address1ZipCode.Length >= 2) { StudentSuperOBJ[record.RefStudentID].ZipCode2 = record.Address1ZipCode.Substring(1, 1); } if (record.Address1ZipCode.Length >= 3) { StudentSuperOBJ[record.RefStudentID].ZipCode3 = record.Address1ZipCode.Substring(2, 1); } if (record.Address1ZipCode.Length >= 4) { StudentSuperOBJ[record.RefStudentID].ZipCode4 = record.Address1ZipCode.Substring(3, 1); } if (record.Address1ZipCode.Length >= 5) { StudentSuperOBJ[record.RefStudentID].ZipCode5 = record.Address1ZipCode.Substring(4, 1); } } } } #endregion #region 取得學生監護人父母親資料 foreach (ParentRecord record in Parent.SelectByStudentIDs(allStudentID)) { StudentSuperOBJ[record.RefStudentID].CustodianName = record.CustodianName; StudentSuperOBJ[record.RefStudentID].FatherName = record.FatherName; StudentSuperOBJ[record.RefStudentID].MotherName = record.MotherName; } //dsrsp = JHSchool.Compatibility.Feature.QueryStudent.GetMultiParentInfo(allStudentID.ToArray()); //foreach (XmlElement var in dsrsp.GetContent().GetElements("ParentInfo")) //{ // string studentID = var.GetAttribute("StudentID"); // studentInfo[studentID].Add("CustodianName", var.SelectSingleNode("CustodianName").InnerText); // studentInfo[studentID].Add("FatherName", var.SelectSingleNode("FatherName").InnerText); // studentInfo[studentID].Add("MotherName", var.SelectSingleNode("MotherName").InnerText); //} #endregion #endregion Document template = new Document(obj.Template); #region 缺曠類別部份 int columnNumber = 0; foreach (List <string> var in config.Values) { columnNumber += var.Count; } #endregion #region 產生報表 Document doc = new Document(); doc.Sections.Clear(); paperForStudent = new SmartSchool.ePaper.ElectronicPaper("缺曠通知單_" + DateTime.Now.Year + DateTime.Now.Month.ToString().PadLeft(2, '0') + DateTime.Now.Day.ToString().PadLeft(2, '0'), School.DefaultSchoolYear, School.DefaultSemester, SmartSchool.ePaper.ViewerType.Student); DataTable dt = new DataTable(); // 2020/01/09 穎驊修正,因應郵局格式要求說明文件中,收件人的姓名、郵遞區號和地址,有規定的欄位名稱(CN,POSTALCODE,POSTALADDRESS),手動填入 dt.Columns.Add("CN"); dt.Columns.Add("POSTALCODE"); dt.Columns.Add("POSTALADDRESS"); foreach (string studentID in StudentSuperOBJ.Keys) { Dictionary <string, object> mappingAccessory = new Dictionary <string, object>(); foreach (string each in mappingAccessory_copy.Keys) { mappingAccessory.Add(each, mappingAccessory_copy[each]); } StudentOBJ eachStudentInfo = StudentSuperOBJ[studentID]; //合併列印的資料 Dictionary <string, object> mapping = new Dictionary <string, object>(); if (!DelStudent.Contains(studentID)) //如果不包含在內,就離開 { continue; } if (obj.PrintHasRecordOnly) { //明細等於0 if (eachStudentInfo.studentAbsenceDetail.Count == 0) { currentStudentCount++; continue; } } Document eachSection = new Document(); eachSection.Sections.Clear(); eachSection.Sections.Add(eachSection.ImportNode(template.Sections[0], true)); MemoryStream accessoryMemory; Aspose.Words.Document accessoryDoc; //學生資料 mappingAccessory.Add("學生姓名", eachStudentInfo.student.Name); mappingAccessory.Add("班級", eachStudentInfo.ClassName); mappingAccessory.Add("座號", eachStudentInfo.SeatNo); mappingAccessory.Add("學號", eachStudentInfo.StudentNumber); mappingAccessory.Add("導師", eachStudentInfo.TeacherName); mappingAccessory.Add("學年度", School.DefaultSchoolYear); mappingAccessory.Add("學期", School.DefaultSemester); mappingAccessory.Add("資料期間", obj.StartDate.ToShortDateString() + " 至 " + obj.EndDate.ToShortDateString()); //懲戒明細 bool IsAccessory = false; //學校資訊 mapping.Add("學校名稱", School.ChineseName); mapping.Add("學校地址", School.Address); mapping.Add("學校電話", School.Telephone); //學生資料 mapping.Add("學生姓名", eachStudentInfo.student.Name); mapping.Add("班級", eachStudentInfo.ClassName); mapping.Add("座號", eachStudentInfo.SeatNo); mapping.Add("學號", eachStudentInfo.StudentNumber); mapping.Add("導師", eachStudentInfo.TeacherName); mapping.Add("資料期間", obj.StartDate.ToShortDateString() + " 至 " + obj.EndDate.ToShortDateString()); // 2019/11/12 穎驊註解 本專案為弘文於本學期提出來的需求,增加家長代碼 mapping.Add("家長代碼", eachStudentInfo.ParentCode); //收件人資料 if (obj.ReceiveName == "監護人姓名") { mapping.Add("收件人姓名", eachStudentInfo.CustodianName); } else if (obj.ReceiveName == "父親姓名") { mapping.Add("收件人姓名", eachStudentInfo.FatherName); } else if (obj.ReceiveName == "母親姓名") { mapping.Add("收件人姓名", eachStudentInfo.MotherName); } else { mapping.Add("收件人姓名", eachStudentInfo.student.Name); } //收件人地址資料 mapping.Add("收件人地址", eachStudentInfo.address); mapping.Add("郵遞區號", eachStudentInfo.ZipCode); mapping.Add("0", eachStudentInfo.ZipCode1); mapping.Add("1", eachStudentInfo.ZipCode2); mapping.Add("2", eachStudentInfo.ZipCode3); mapping.Add("4", eachStudentInfo.ZipCode4); mapping.Add("5", eachStudentInfo.ZipCode5); mapping.Add("學年度", School.DefaultSchoolYear); mapping.Add("學期", School.DefaultSemester); //缺曠學期統計部份 int columnIndex = 1; int DefinedTypeCount = 1; foreach (string attendanceType in configkeylist) { int DefinedAbsenceCount = 1; foreach (string absenceType in config[attendanceType]) { string dataValue = "0"; string semesterDataValue = "0"; string PeriodAndAbsence = attendanceType + "," + absenceType; //本期統計 if (eachStudentInfo.studentAbsence.ContainsKey(PeriodAndAbsence)) { dataValue = eachStudentInfo.studentAbsence[PeriodAndAbsence].ToString(); } //學期統計 if (eachStudentInfo.studentSemesterAbsence.ContainsKey(PeriodAndAbsence)) { semesterDataValue = eachStudentInfo.studentSemesterAbsence[PeriodAndAbsence].ToString(); } mapping.Add("類型" + DefinedTypeCount + "本期" + DefinedAbsenceCount, dataValue); mapping.Add("類型" + DefinedTypeCount + "學期" + DefinedAbsenceCount, semesterDataValue); DefinedAbsenceCount++; columnIndex++; } DefinedTypeCount++; } // 2020/02/07 嘉詮與學校後 確立 格式固定要有 日期1~日期12 且每日節次1~12,故總變數為日期1節次1 ~ 日期12節次12 for (int date = 1; date <= 12; date++) { mapping.Add("日期" + date, ""); for (int peroid = 1; peroid <= 12; peroid++) { mapping.Add("日期" + date + "節次" + peroid, ""); } } //缺曠明細 int DateCount = 1; foreach (string each in eachStudentInfo.studentAbsenceDetail.Keys) { int Period = 1; //資料數大於10,透過附件列印 if (DateCount <= 12) { if (mapping.ContainsKey("日期" + DateCount)) { mapping["日期" + DateCount] = Switching(each); } else { mapping.Add("日期" + DateCount, Switching(each)); } } else { mappingAccessory.Add("日期" + DateCount, Switching(each)); } //取得節次清單,一一檢查是否有資料要填 foreach (string Date in eachStudentInfo.studentAbsenceDetail[each].Keys) { string detail = eachStudentInfo.studentAbsenceDetail[each][Date]; if (absenceList.ContainsKey(detail)) { if (ReversionDic.ContainsKey(Date)) { if (DateCount <= 12) //資料數大於10,透過附件列印 { if (mapping.ContainsKey("日期" + DateCount + ReversionDic[Date])) { mapping["日期" + DateCount + ReversionDic[Date]] = absenceList[detail]; } else { mapping.Add("日期" + DateCount + ReversionDic[Date], absenceList[detail]); } Period++; } else { mappingAccessory.Add("日期" + DateCount + ReversionDic[Date], absenceList[detail]); IsAccessory = true; Period++; } } } } DateCount++; } //學生個人資料 string[] keys = new string[mapping.Count]; object[] values = new object[mapping.Count]; int i = 0; foreach (string key in mapping.Keys) { keys[i] = key; values[i++] = mapping[key]; } eachSection.MailMerge.Execute(keys, values); //整體資料 string[] Allkeys = new string[Allmapping.Count]; object[] Allvalues = new object[Allmapping.Count]; int t = 0; foreach (string key in Allmapping.Keys) { Allkeys[t] = key; Allvalues[t++] = Allmapping[key]; } eachSection.MailMerge.Execute(Allkeys, Allvalues); eachSection.MailMerge.DeleteFields(); #region epost 使用 // 將對應功能變數 套入dt foreach (string key in mapping.Keys) { if (!dt.Columns.Contains(key)) { dt.Columns.Add(key); } } foreach (string key in Allmapping.Keys) { if (!dt.Columns.Contains(key)) { dt.Columns.Add(key); } } DataRow row = dt.NewRow(); row["CN"] = mapping["收件人姓名"]; row["POSTALCODE"] = mapping["郵遞區號"]; row["POSTALADDRESS"] = mapping["收件人地址"]; foreach (string key in mapping.Keys) { row[key] = mapping[key]; } foreach (string key in Allmapping.Keys) { row[key] = Allmapping[key]; } dt.Rows.Add(row); #endregion if (IsAccessory) { accessoryMemory = new MemoryStream(Properties.Resources.缺曠通知單_附件一); accessoryDoc = new Aspose.Words.Document(accessoryMemory); string[] keysAccessory = new string[mappingAccessory.Count]; object[] valuesAccessory = new object[mappingAccessory.Count]; int xx = 0; foreach (string key in mappingAccessory.Keys) { keysAccessory[xx] = key; valuesAccessory[xx++] = mappingAccessory[key]; } accessoryDoc.MailMerge.CleanupOptions = Aspose.Words.Reporting.MailMergeCleanupOptions.RemoveEmptyParagraphs; accessoryDoc.MailMerge.Execute(keysAccessory, valuesAccessory); accessoryDoc.MailMerge.DeleteFields(); //刪除未合併之內容 Aspose.Words.Node eachSectionaccessory = accessoryDoc.Sections[0].Clone(); eachSection.Sections.Add(eachSection.ImportNode(eachSectionaccessory, true)); MemoryStream stream = new MemoryStream(); eachSection.Save(stream, SaveFormat.Doc); paperForStudent.Append(new PaperItem(PaperFormat.Office2003Doc, stream, eachStudentInfo.student.ID)); } else { MemoryStream stream = new MemoryStream(); eachSection.Save(stream, SaveFormat.Doc); paperForStudent.Append(new PaperItem(PaperFormat.Office2003Doc, stream, eachStudentInfo.student.ID)); } foreach (Aspose.Words.Section each in eachSection.Sections) { Aspose.Words.Node eachSectionNode = each.Clone(); doc.Sections.Add(doc.ImportNode(eachSectionNode, true)); } //回報進度 _BGWAbsenceNotification.ReportProgress((int)(((double)currentStudentCount++ *100.0) / (double)totalStudentNumber)); } #endregion #region 產生學生清單 Aspose.Cells.Workbook wb = new Aspose.Cells.Workbook(); if (obj.PrintStudentList) { int CountRow = 0; wb.Worksheets[0].Cells[CountRow, 0].PutValue("班級"); wb.Worksheets[0].Cells[CountRow, 1].PutValue("座號"); wb.Worksheets[0].Cells[CountRow, 2].PutValue("學號"); wb.Worksheets[0].Cells[CountRow, 3].PutValue("學生姓名"); wb.Worksheets[0].Cells[CountRow, 4].PutValue("收件人姓名"); wb.Worksheets[0].Cells[CountRow, 5].PutValue("地址"); wb.Worksheets[0].Cells[CountRow, 6].PutValue("家長代碼"); CountRow++; foreach (string each in StudentSuperOBJ.Keys) { if (!DelStudent.Contains(each)) //如果不包含在內,就離開 { continue; } if (obj.PrintHasRecordOnly) { //明細等於0 if (StudentSuperOBJ[each].studentAbsenceDetail.Count == 0) { currentStudentCount++; continue; } } wb.Worksheets[0].Cells[CountRow, 0].PutValue(StudentSuperOBJ[each].ClassName); wb.Worksheets[0].Cells[CountRow, 1].PutValue(StudentSuperOBJ[each].SeatNo); wb.Worksheets[0].Cells[CountRow, 2].PutValue(StudentSuperOBJ[each].StudentNumber); wb.Worksheets[0].Cells[CountRow, 3].PutValue(StudentSuperOBJ[each].student.Name); //收件人資料 if (obj.ReceiveName == "監護人姓名") { wb.Worksheets[0].Cells[CountRow, 4].PutValue(StudentSuperOBJ[each].CustodianName); } else if (obj.ReceiveName == "父親姓名") { wb.Worksheets[0].Cells[CountRow, 4].PutValue(StudentSuperOBJ[each].FatherName); } else if (obj.ReceiveName == "母親姓名") { wb.Worksheets[0].Cells[CountRow, 4].PutValue(StudentSuperOBJ[each].MotherName); } else { wb.Worksheets[0].Cells[CountRow, 4].PutValue(StudentSuperOBJ[each].student.Name); } wb.Worksheets[0].Cells[CountRow, 5].PutValue(StudentSuperOBJ[each].ZipCode + " " + StudentSuperOBJ[each].address); wb.Worksheets[0].Cells[CountRow, 6].PutValue(StudentSuperOBJ[each].ParentCode); CountRow++; } wb.Worksheets[0].AutoFitColumns(); } #endregion //是否上傳電子報表 if (obj.PaperUpdate) { SmartSchool.ePaper.DispatcherProvider.Dispatch(paperForStudent); } string path = Path.Combine(Application.StartupPath, "Reports"); string path2 = Path.Combine(Application.StartupPath, "Reports"); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } path = Path.Combine(path, reportName + ".docx"); path2 = Path.Combine(path2, reportName + "(學生清單).xlsx"); e.Result = new object[] { reportName, path, doc, path2, obj.PrintStudentList, wb, dt }; }