XML映射中的多个Excel表

时间:2012-01-17 19:48:23

标签: xml excel vba reporting

我正在尝试使用XML中的销售数据生成Excel 2007文件(请参阅下面的第1张图片)。棘手的部分是我想要每个<item>元素的图表(见下面的第2张图片)。对于最终产品,我将在.baltm模板中的vba中构建此逻辑,该模板将根据给定的XML生成大约800个项目销售表。

(我已经使用过很多Excel VBA及其查询表/工作簿连接,但我是数据导入的XML方面的新手,所以请耐心等待。)

我的第一个想法是使用XML地图。我希望能够多次复制相同的元素映射,但将其映射到特定的<item name"x">元素(所有这些都通过VBA),但看起来这不是一个选项(除非它在VBA中是隐藏的功能,我'我不知道?)。

我可以使用不同的项目名称作为元素(即<item1><item2>等)而不是<item>,因此每个项目都是我自己的元素,我将单独映射。这不是有点hacky吗?我是XML世界的新手,这听起来并不像是被认为是格式良好的。我的目标是使用相同的概念,在许多不同的报告目的上生成“位大小的图表”,所以我希望找到一个优雅的过程。

似乎我唯一的选择是使用hacky XML映射(请参见下面的第3张图片),其中每个图表都是自己的元素标记,然后以某种方式迭代并将每个元素的图表放在具有VBA的工作表上。 (不确定800的映射是否会影响Excel的性能)

任何建议都会受到赞赏。我认为这是Excel高级用户的常见需求,但我很难找到有关此概念的信息。如果这个概念可以用其他方法(即查询表等),我可以接受任何解决方案。对于这种视觉风格的报告而言,XML似乎最适合于表格式报告。

如果需要重组以适应方法,我可以完全控制源XML模式。此外,为了举例,所有数据/格式都被贬低了。

报告格式示例:
desc1

XML数据格式代码段
desc2

Hacky XML Mapping Method
desc3

1 个答案:

答案 0 :(得分:0)

我使用过这样的东西在一张纸上创建多个表以及多张表..

            var data = Collection1;
            var data1 = Collection2;
            var name = "sheet name";

            const int left = 1;
            const int top = 3;
            int height = data.GetLength(0);
            int width = data.GetLength(1);
            int bottom = top + height - 1;
            int right = left + width - 1;

            var exxapp = new Microsoft.Office.Interop.Excel.Application();
            Workbook xlWorkBook = exxapp.Workbooks.Add(Missing.Value);
            var xlWorkSheet = (Worksheet)xlWorkBook.Sheets.Item[1];
            xlWorkSheet.Name = "sheet name";
            exxapp.ScreenUpdating = false;
            if (height == 0 || width == 0)
                return;
            dynamic rgtitle = xlWorkSheet.Range[xlWorkSheet.Cells[1, 1], xlWorkSheet.Cells[1, 1]];
            rgtitle.Value = "Table Heading  :-  " + name;
            rgtitle.EntireColumn.AutoFit();

            dynamic rg = xlWorkSheet.Range[xlWorkSheet.Cells[top, left], xlWorkSheet.Cells[bottom, right]];
            rg.Value = data;
            // Set borders
            for (int i = 1; i <= 4; i++)
                rg.Borders[i].LineStyle = 1;
            // Set auto columns width
            rg.EntireColumn.AutoFit();
            // Set header view
            dynamic rgHeader = xlWorkSheet.Range[xlWorkSheet.Cells[top, left], xlWorkSheet.Cells[top, right]];
            rgHeader.Font.Bold = true;
            rgHeader.Interior.Color = 189 * (int)Math.Pow(16, 4) + 129 * (int)Math.Pow(16, 2) + 78; // #4E81BD
            const int left1 = 1;
            const int top1 = 1;
            int height1 = data1.GetLength(0);
            int width1 = data1.GetLength(1);
            int bottom1 = top1 + height1 - 1;
            int right1 = left1 + width1 - 1;

            xlWorkSheet = (Worksheet)xlWorkBook.Sheets.Item[2];
            xlWorkSheet.Name = "second sheet name";
            exxapp.ScreenUpdating = false;
            if (height1 == 0 || width1 == 0)
                return;
            dynamic rg1 = xlWorkSheet.Range[xlWorkSheet.Cells[top1, left1], xlWorkSheet.Cells[bottom1, right1]];
            rg1.Value = data1;
            // Set borders
            for (int i = 1; i <= 4; i++)
                rg1.Borders[i].LineStyle = 1;

            // Set auto columns width
            rg1.EntireColumn.AutoFit();

            // Set header view
            dynamic rgHeader1 = xlWorkSheet.Range[xlWorkSheet.Cells[top1, left1], xlWorkSheet.Cells[top1, right1]];
            rgHeader1.Font.Bold = true;
            rgHeader1.Interior.Color = 189 * (int)Math.Pow(16, 4) + 129 * (int)Math.Pow(16, 2) + 78; // #4E81BD

            // Show excel app
            exxapp.ScreenUpdating = true;
            exxapp.Visible = true;


            Marshal.ReleaseComObject(rg);
            Marshal.ReleaseComObject(rgHeader);
            Marshal.ReleaseComObject(rg1);
            Marshal.ReleaseComObject(rgHeader1);
            Marshal.ReleaseComObject(xlWorkSheet);
            Marshal.ReleaseComObject(xlWorkBook);
            Marshal.ReleaseComObject(exxapp);

            GC.Collect();