使用 Aspose.Words 外掛在 Word 畫 EChart 圖
使用此外掛可以畫出豐富的 EChart 圖,API 參考 https://reference.aspose.com/words/net/aspose.words.drawing.charts/charttype/
首先需要在 vs 中引入外掛
程式碼中新增參照
using Aspose.Words; using Aspose.Words.Drawing.Charts; using Aspose.Words.Tables;
1、插入文字內容和表格
我們只需要獲取模板,並且建立一個檔案物件,將內容寫入進去即可
建立表格時,需要建立頭,規定每個單元格長度,寬度,將對應的資料庫欄位對應上
1 DataTable dt = new DataTable(); 2 3 //讀取 Word 模板 4 Document doc = new Document("C:\\TestProject\\WebApplication1\\WebApplication1\\Word\\AsposeWord.doc"); 5 6 //建立檔案物件 7 DocumentBuilder builder = new DocumentBuilder(doc); 8 9 #region 插入文字資訊 10 //Word 中對應書籤的名稱 11 builder.MoveToBookmark("文章標題"); 12 13 //寫入內容 14 builder.Write("學會使用AsposeWord畫EChart圖"); 15 #endregion 16 17 #region 列表 18 builder.MoveToBookmark("學生資訊列表"); 19 20 Aspose.Words.Tables.Table table3 = builder.StartTable();//開始畫Table 21 string[] columnheadersWD = { "序號", "姓名", "學科", "分數", "性別", "年齡" }; 22 string[] columnnamesWD = { "ID", "TNAME", "DNAME", "SAL", "TSEX", "AGE" }; 23 double[] colwidthsWD = { 50, 100, 100, 50, 50, 50 }; 24 25 dt = DBHelper.ExecuteDataTable("SELECT top 5 * FROM [testdb].[dbo].[TEACHER]"); 26 27 InsertTable(builder, table3, columnheadersWD, columnnamesWD, colwidthsWD, dt); 28 29 //第三列的 第三行,第四行 合併 30 MergeCells(table3.Rows[3].Cells[2], table3.Rows[4].Cells[2]); 31 #endregion
這裡我們將畫表格的方法和合並單元格的方法封裝好了
1 /// <summary> 2 /// 列表表格 3 /// </summary> 4 /// <param name="builder"></param> 5 /// <param name="table"></param> 6 /// <param name="columnheaders"></param> 7 /// <param name="columnnames"></param> 8 /// <param name="colwidths"></param> 9 /// <param name="statisTable"></param> 10 public static void InsertTable(DocumentBuilder builder, Aspose.Words.Tables.Table table, string[] columnheaders, string[] columnnames, double[] colwidths, DataTable statisTable) 11 { 12 var str = ""; 13 14 #region 畫表頭 15 for (int i = 0; i < columnheaders.Length; i++) 16 { 17 str = columnheaders[i]; 18 builder.InsertCell(); 19 //Table單元格邊框線樣式 20 builder.CellFormat.Borders.LineStyle = LineStyle.Single; 21 //Table此單元格寬度 22 builder.RowFormat.Height = 30; 23 builder.CellFormat.Width = colwidths[i]; 24 //此單元格中內容垂直對齊方式 25 builder.CellFormat.VerticalAlignment = Aspose.Words.Tables.CellVerticalAlignment.Center; 26 builder.CellFormat.HorizontalMerge = Aspose.Words.Tables.CellMerge.None; 27 builder.CellFormat.VerticalMerge = Aspose.Words.Tables.CellMerge.None; 28 //字型大小 29 builder.Font.Size = 10; 30 //是否加粗 31 builder.Bold = false; 32 //向此單元格中新增內容 33 builder.Write(str); 34 } 35 builder.EndRow(); 36 #endregion 37 38 #region 畫資料 39 for (int j = 0; j < statisTable.Rows.Count; j++) 40 { 41 for (int i = 0; i < columnheaders.Length; i++) 42 { 43 try 44 { 45 str = statisTable.Rows[j][columnnames[i]].ToString(); 46 } 47 catch (Exception e) { str = ""; } 48 builder.InsertCell(); 49 //Table單元格邊框線樣式 50 builder.CellFormat.Borders.LineStyle = LineStyle.Single; 51 //Table此單元格寬度 52 builder.RowFormat.Height = 30; 53 builder.CellFormat.Width = colwidths[i]; 54 55 //builder.CellFormat.Shading.ForegroundPatternColor = Color.Red;//設定單元格顏色 56 57 //此單元格中內容垂直對齊方式 58 builder.CellFormat.VerticalAlignment = Aspose.Words.Tables.CellVerticalAlignment.Center; 59 builder.CellFormat.HorizontalMerge = Aspose.Words.Tables.CellMerge.None; 60 builder.CellFormat.VerticalMerge = Aspose.Words.Tables.CellMerge.None; 61 //字型大小 62 builder.Font.Size = 10; 63 //是否加粗 64 builder.Bold = false; 65 //向此單元格中新增內容 66 builder.Write(str); 67 } 68 builder.EndRow(); 69 } 70 #endregion 71 72 //Table行結束 73 builder.EndTable(); 74 table.AutoFit(Aspose.Words.Tables.AutoFitBehavior.FixedColumnWidths); 75 table.Alignment = Aspose.Words.Tables.TableAlignment.Center; 76 } 77 78 /// <summary> 79 /// 合併單元格 80 /// </summary> 81 /// <param name="startCell"></param> 82 /// <param name="endCell"></param> 83 public static void MergeCells(Cell startCell, Cell endCell) 84 { 85 Aspose.Words.Tables.Table parentTable = startCell.ParentRow.ParentTable; 86 87 // Find the row and cell indices for the start and end cell. 88 Point startCellPos = new Point(startCell.ParentRow.IndexOf(startCell), parentTable.IndexOf(startCell.ParentRow)); 89 Point endCellPos = new Point(endCell.ParentRow.IndexOf(endCell), parentTable.IndexOf(endCell.ParentRow)); 90 // Create the range of cells to be merged based off these indices. Inverse each index if the end cell if before the start cell. 91 Rectangle mergeRange = new Rectangle(Math.Min(startCellPos.X, endCellPos.X), Math.Min(startCellPos.Y, endCellPos.Y), Math.Abs(endCellPos.X - startCellPos.X) + 1, 92 Math.Abs(endCellPos.Y - startCellPos.Y) + 1); 93 94 foreach (Row row in parentTable.Rows) 95 { 96 foreach (Cell cell in row.Cells) 97 { 98 Point currentPos = new Point(row.IndexOf(cell), parentTable.IndexOf(row)); 99 100 // Check if the current cell is inside our merge range then merge it. 101 if (mergeRange.Contains(currentPos)) 102 { 103 if (currentPos.X == mergeRange.X) 104 cell.CellFormat.HorizontalMerge = CellMerge.First; 105 else 106 cell.CellFormat.HorizontalMerge = (CellMerge.Previous); 107 108 if (currentPos.Y == mergeRange.Y) 109 cell.CellFormat.VerticalMerge = (CellMerge.First); 110 else 111 cell.CellFormat.VerticalMerge = (CellMerge.Previous); 112 } 113 } 114 } 115 }
2、單雙曲線圖,餅圖,柱狀圖
曲線圖需要用到 InsertChart 方法指定圖表型別 Line,這三種圖區別不大方法一樣,只需要指定圖表型別
ChartSeriesCollection seriesCollection = chart.Series; 提供了向圖表插入資料的操作,有點類似 List 如果你只有一條曲線(柱狀圖),寫一個 Add 就行,如果是多條曲線(柱狀圖),則新增多個 Add 資料即可展示多條曲線(柱狀圖)
1 #region 曲線 2 builder.MoveToBookmark("雙曲線"); 3 var shape = builder.InsertChart(ChartType.Line, 430, 210);//插入線形圖 4 Chart chart = shape.Chart; 5 ChartSeriesCollection seriesCollection = chart.Series; 6 seriesCollection.Clear();//清除預設 7 chart.Title.Text = "雙曲線"; 8 chart.AxisX.TickLabelPosition = AxisTickLabelPosition.Low; 9 10 dt = DBHelper.ExecuteDataTable("select top 5 TNAME,sal,sal+100 as SAL1 from TEACHER"); 11 12 var categories = new string[dt.Rows.Count]; 13 var values = new double[dt.Rows.Count]; 14 var values1 = new double[dt.Rows.Count]; 15 16 for (int rowIndex = 0; rowIndex < dt.Rows.Count; rowIndex++) 17 { 18 categories[rowIndex] = dt.Rows[rowIndex][0].ToString(); 19 values[rowIndex] = Convert.ToDouble(dt.Rows[rowIndex][1]); 20 values1[rowIndex] = Convert.ToDouble(dt.Rows[rowIndex][2]); 21 } 22 23 chart.Legend.Position = LegendPosition.Top; 24 25 seriesCollection.Add("線條一", categories, values);//新增資料 26 seriesCollection.Add("線條二", categories, values1);//新增資料 27 #endregion 28 29 #region 餅狀圖 30 dt = DBHelper.ExecuteDataTable("select top 1 sal,sal+100 as SAL1,sal+200 as SAL2 from TEACHER"); 31 32 List<CountModel> list1 = new List<CountModel>(); 33 for (int i = 0; i < dt.Rows.Count; i++) 34 { 35 list1.Add(new CountModel { mark = "一", num = Convert.ToDouble(dt.Rows[i][0]) }); 36 list1.Add(new CountModel { mark = "二", num = Convert.ToDouble(dt.Rows[i][1]) }); 37 list1.Add(new CountModel { mark = "三", num = Convert.ToDouble(dt.Rows[i][2]) }); 38 } 39 40 builder.MoveToBookmark("餅狀圖"); 41 var shape1 = builder.InsertChart(ChartType.Pie, 430, 210);//插入線形圖 42 Chart chart1 = shape1.Chart; 43 ChartSeriesCollection seriesCollection1 = chart1.Series; 44 seriesCollection1.Clear();//清除預設 45 chart1.Title.Text = "餅狀圖"; 46 47 var categories2 = new string[list1.Count]; 48 var values2 = new double[list1.Count]; 49 50 for (int rowIndex = 0; rowIndex < list1.Count; rowIndex++) 51 { 52 categories2[rowIndex] = list1[rowIndex].mark.ToString(); 53 values2[rowIndex] = Convert.ToDouble(list1[rowIndex].num); 54 } 55 56 chart1.Legend.Position = LegendPosition.Top; 57 58 seriesCollection1.Add("餅狀圖", categories2, values2);//新增資料 59 #endregion 60 61 #region 柱狀圖 62 dt = DBHelper.ExecuteDataTable("select top 5 tname,sal,sal+100 as SAL1,sal+200 as SAL2 from TEACHER"); 63 64 builder.MoveToBookmark("柱狀圖"); 65 var shape2 = builder.InsertChart(ChartType.Column, 430, 210);//插入線形圖 66 Chart chart2 = shape2.Chart; 67 ChartSeriesCollection seriesCollection3 = chart2.Series; 68 seriesCollection3.Clear();//清除預設 69 chart2.Title.Text = "柱狀圖"; 70 chart2.AxisX.TickLabelPosition = AxisTickLabelPosition.Low; 71 72 var categories3 = new string[dt.Rows.Count]; 73 var values11 = new double[dt.Rows.Count]; 74 var values22 = new double[dt.Rows.Count]; 75 var values3 = new double[dt.Rows.Count]; 76 77 for (int rowIndex = 0; rowIndex < dt.Rows.Count; rowIndex++) 78 { 79 categories3[rowIndex] = dt.Rows[rowIndex][0].ToString(); 80 values11[rowIndex] = Convert.ToDouble(dt.Rows[rowIndex][1]); 81 values22[rowIndex] = Convert.ToDouble(dt.Rows[rowIndex][2]); 82 values3[rowIndex] = Convert.ToDouble(dt.Rows[rowIndex][3]); 83 } 84 85 chart2.Legend.Position = LegendPosition.Top; 86 87 seriesCollection3.Add("一", categories3, values11);//新增資料 88 seriesCollection3.Add("二", categories3, values22);//新增資料 89 seriesCollection3.Add("三", categories3, values3);//新增資料 90 #endregion
3、散點圖
散點圖跟其他圖略有區別,散點圖是 XY 的座標點形式處理資料
1 #region 散點圖 2 var result = new List<SD>(); 3 result.Add(new SD() { wd = 15, wy = 16 }); 4 result.Add(new SD() { wd = 14, wy = 23 }); 5 result.Add(new SD() { wd = 34, wy = 23 }); 6 result.Add(new SD() { wd = 12, wy = 23 }); 7 result.Add(new SD() { wd = 34, wy = 45 }); 8 result.Add(new SD() { wd = 32, wy = 23 }); 9 result.Add(new SD() { wd = 45, wy = 56 }); 10 result.Add(new SD() { wd = 34, wy = 55 }); 11 12 builder.MoveToBookmark("散點圖"); 13 var shape3 = builder.InsertChart(ChartType.Scatter, 430, 210);//插入線形圖 14 Chart chart3 = shape3.Chart; 15 ChartSeriesCollection seriesCollection4 = chart3.Series; 16 seriesCollection4.Clear();//清除預設 17 chart3.Title.Text = "散點圖"; 18 chart3.AxisX.TickLabelPosition = AxisTickLabelPosition.Low; 19 20 var categories4 = new double[result.Count]; 21 var values4 = new double[result.Count]; 22 23 for (int i = 0; i < result.Count; i++) 24 { 25 categories4[i] = Convert.ToDouble(result[i].wd); 26 values4[i] = Convert.ToDouble(result[i].wy); 27 } 28 29 chart3.Legend.Position = LegendPosition.Top; 30 seriesCollection4.Add("散點圖", categories4, values4);//新增資料 31 #endregion
最後將內容輸出到指定的新檔案中
1 string cpath = "C:\\TestProject\\測試檔案存放\\檔案" + DateTime.Now.ToString("ddhhmmss") + ".doc"; 2 doc.Save(cpath); 3 doc.Save(cpath.Replace(".doc", ".pdf"), SaveFormat.Pdf); //同時轉成 PDF 生成一份
這裡只是簡單的操作顯示圖表,如果需要具體詳細的細節操作,參考官方提供的API檔案。
效果圖