天天看点

使用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);