天天看點

使用Aspose.Cell控件實作Excel高難度報表的生成(二)

 或者這樣的報表格式

首先來分析第一種報表,這個其實還是比較固定的二維表,我們隻要綁定相關的資訊即可,設計模闆如下所示:

實際生成的報表如下所示:

實作的代碼其實不複雜,如下所示:

         private DataTable GetTable(string sql)

        {

            Database db = DatabaseFactory.CreateDatabase();

            DbCommand command = db.GetSqlStringCommand(sql);

            return db.ExecuteDataSet(command).Tables[0];

        }

        private void btnAllMonthReport_Click(object sender, EventArgs e)

            string sql = @"Select [LastCount] as LC, [LastMoney] as LM, [CurrentInCount] as CIC, [CurrentInMoney] as CIM, 

                           [CurrentOutCount] as COC, [CurrentOutMoney] as COM, [CurrentCount] as CC, [CurrentMoney] as CM, 

                           YearMonth,ItemName 

                           from TB_ReportMonthCheckOut ";

            DataTable dtBigType = GetTable(sql + " where ReportType =3");

            dtBigType.TableName = "BigType";

            if (dtBigType.Rows.Count == 0)

                return;

            DataTable dtItemType = GetTable(sql + " where ReportType =3");

            dtItemType.TableName = "ItemType";

            WorkbookDesigner designer = new WorkbookDesigner();

            string path = System.IO.Path.Combine(Application.StartupPath, "Report2-1.xls");

            designer.Open(path);

            designer.SetDataSource(dtBigType);

            designer.SetDataSource(dtItemType);

            designer.SetDataSource("YearMonth", dtBigType.Rows[0]["YearMonth"].ToString());

            designer.Process();

            //Save the excel file

            string fileToSave = FileDialogHelper.SaveExcel();

            if (File.Exists(fileToSave))

            {

                File.Delete(fileToSave);

            }

            designer.Save(fileToSave, FileFormatType.Excel2003);

            Process.Start(fileToSave);

通過綁定兩個不同的DataTable對象,然後引用他的屬性即可,行會自動增加以适應實際的資料,并且對象變量&=$YearMonth也正常顯示了,注意一點就是,所有使用變量的地方,都必須在一個獨立的Excel單元格中,否則不能解析出來。另外上圖的紅色圓圈裡面表示,彙總的函數,會自動根據行列的增加,自動調整引用,這真是我們需要的。 

 出庫單的實作也差不多,實作代碼如下所示:

            string TakeOutBill = Path.Combine(Application.StartupPath, "TakeOutBill.xls");

            designer.Open(TakeOutBill);

            designer.SetDataSource("TakeOutDate", DateTime.Now.ToString("yyyy-MM-dd"));

            designer.SetDataSource("WareHouse", this.txtWareHouse.Text);

            designer.SetDataSource("Manager", this.txtCreator.Text);

            designer.SetDataSource("CostCenter", this.txtCostCenter.Text);

            designer.SetDataSource("Dept", this.txtDept.Text);

            string columns = "Start|int,ItemNo,ItemName,Specification,Unit,Price|decimal,Count|int";

            DataTable dt = DataTableHelper.CreateTable(columns);

            dt.TableName = "Detail";

            DataRow row = null;

            for (int i = 0; i < this.lvwDetail.Items.Count; i++)

                PurchaseDetailInfo info = this.lvwDetail.Items[i].Tag as PurchaseDetailInfo;

                if (info != null)

                {

                    row = dt.NewRow();

                    row["Start"] = (i + 1);

                    row["ItemNo"] = info.ItemNo;

                    row["ItemName"] = info.ItemName;

                    row["Specification"] = info.Specification;

                    row["Unit"] = info.Unit;

                    row["Price"] = info.Price;

                    row["Count"] = Math.Abs(info.Quantity);

                    dt.Rows.Add(row);

                }

            designer.SetDataSource(dt);

            Process.Start(fileToSave);

以上報表,其實實作思路基本都差不多,相對來時,還是比較容易的,接下來設計一個比較困難的報表,需要結合Aspose.Cell一些對象來動态建立行列,并設定單元格的變量,然後填入相應的對象構造報表,另外還需要注意單元格格式的變化,如下所示的這種報表

這個報表初看沒有太多特别的地方,難點就是他的第一行列也是變化的,是以不能通過普通的方式建構二維表,然後綁定資料源的方式,要先加載模闆檔案,然後操作Excel對象,把第一行的各列頭部補齊,然後給下一行各單元格填入對象公式,如&=BigType.DeptName 和&=BigType.TotalMoney等内容,實作的代碼如下所示:

            string sql = @"Select [YearMonth], [DeptName], [ItemType], [TotalMoney]

                           from TB_ReportDeptCost ";

            DataTable dt = GetTable(sql);

            if (dt.Rows.Count == 0)

            List<string> itemTypeList = new List<string>();

            List<string> partList = new List<string>();

            foreach (DataRow row in dt.Rows)

                string itemType = row["ItemType"].ToString();

                if (!itemTypeList.Contains(itemType))

                    itemTypeList.Add(itemType);

                string part = row["DeptName"].ToString();

                if (!partList.Contains(part))

                    partList.Add(part);

            string columnString = "DeptName";

            for (int i = 0; i < itemTypeList.Count; i++)

                columnString += string.Format(",TotalMoney{0}|decimal", i);

            DataTable dtBigType = DataTableHelper.CreateTable(columnString);

            foreach (string part in partList)

                DataRow row = dtBigType.NewRow();

                row["DeptName"] = part;

                for (int i = 0; i < itemTypeList.Count; i++)

                    string itemType = itemTypeList[i];

                    DataRow[] rowSelect = dt.Select(string.Format("DeptName='{0}' AND ItemType='{1}'", part, itemType));

                    if (rowSelect.Length > 0)

                    {

                        row["TotalMoney" + i.ToString()] = rowSelect[0]["TotalMoney"];

                    }

                dtBigType.Rows.Add(row);

            string path = System.IO.Path.Combine(Application.StartupPath, "Report1.xls");

            Aspose.Cells.Worksheet w = designer.Workbook.Worksheets[0];

            //先設定标題項目:如大修件,日常備件等

            int rowIndex = 2;//第三行為标題

            Aspose.Cells.Style style = w.Cells[rowIndex + 1, 1].Style;//繼承數字欄目的樣式

            style.Number = 4;//對應格式是#,##0.00

            Aspose.Cells.Style boldStyle = w.Cells[rowIndex, 0].Style;//繼承開始欄目的樣式

                w.Cells[rowIndex, i + 1].PutValue(itemTypeList[i]);

                w.Cells[rowIndex, i + 1].Style = boldStyle;

                w.Cells[rowIndex + 1, i + 1].PutValue("&=BigType.TotalMoney" + i.ToString());

                w.Cells[rowIndex + 1, i + 1].Style = style;

            //添加合計行

            w.Cells[rowIndex, itemTypeList.Count + 1].PutValue("合計");

            w.Cells[rowIndex, itemTypeList.Count + 1].Style = boldStyle;

            w.Cells[rowIndex + 1, itemTypeList.Count + 1].PutValue(string.Format("&=&=SUM(B{{r}}:{0}{{r}})", GetChar(itemTypeList.Count + 1)));

            w.Cells[rowIndex + 1, itemTypeList.Count + 1].Style = style;

            designer.SetDataSource("YearMonth", dt.Rows[0]["YearMonth"].ToString());

            Process.Start(fileToSave);