从XML文件中复用文档rdlc [英] Multimple document rdlc from XML file

查看:86
本文介绍了从XML文件中复用文档rdlc的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,



我能够成功生成并填写rdlc报告(发票类型文件{ DTE }) xml文件通过数据集。



这个rdlc有各种部分,有些需要单个字段,有些需要矩阵。到目前为止,这么好!



以下是此类xml文件的示例:



Hello all,

I am able to successfully generate and populate a rdlc report (invoice type document {DTE}) from a xml file by means of a dataset.

This rdlc has various sections, some require single fields, and some require matrices. So far, so good!

Here's a sample of such xml file:

<?xml version="1.0" encoding="ISO-8859-1"?>
<SetDTE>
<DTE version="1.0" >
<Documento ID="MiPE76266617-2495">
    <Encabezado>
    	...
    </Encabezado>
    <Detalle>
    	...
    </Detalle>
</DTE>
</SetDTE>



这就是我分配/填充每个数据源的方式:


and this is how I assign/populate each DataSource:

RepVwer.LocalReport.DataSources.Clear();
RepVwer.LocalReport.DataSources.Add(new ReportDataSource("Documento", dsXML.Tables[0]));
RepVwer.LocalReport.DataSources.Add(new ReportDataSource("Emisor", dsXML.Tables[1]));
RepVwer.LocalReport.DataSources.Add(new ReportDataSource("Receptor", dsXML.Tables[2]));
RepVwer.LocalReport.DataSources.Add(new ReportDataSource("IdDoc", dsXML.Tables[3]));





情况是这些xml文件现在可以拥有多个文档;即

整个相同的节点结构(子),其中每个都代表一个文件{ DTE }。



例如:





The situation is that a these xml files can now have more that one document; i.e.
entire identical node structures (children), where each one represents a document {DTE}.

Example:

<?xml version="1.0" encoding="ISO-8859-1"?>
<SetDTE>
<DTE version="1.0" >
<Documento ID="MiPE76266617-720">
    <Encabezado>
    	...
    </Encabezado>
    <Detalle>
			...
    </Detalle>
    <Detalle>
			...
    </Detalle>
</DTE>
<DTE version="1.0" >
<Documento ID="MiPE76266617-2495">
    <Encabezado>
    	...
    </Encabezado>
    <Detalle>
    	...
    </Detalle>
</DTE>
</SetDTE>





如何重新编写rdlc以适应这种情况?它应该复制每个文档的整个结构(单个字段和矩阵)。



我注意到在这种情况下,数据集中的每个表都有一个ID字段,可以帮助识别/链接数据表之间的相关记录。



我尝试过:



我一直在网上寻找洞察力,但到目前为止找不到任何相关内容(不确定要寻找什么)。 2018/01/09 ::到目前为止,似乎嵌套矩阵仅在所有数据都包含在同一数据源中时才起作用;因为我有几个数据源,可能无法实现我的目标



我试图使用List控件,但到目前为止一直无法弄清楚如何工作团体,内部矩阵等。



提前感谢大家的意见!



2018/01/09 16:54(UTC -04:00):: 经过一些研究,我遇到了如何合并数据表(第一次) 。这种方法允许我成功地将大多数数据表对象合并到一个大的on,这反过来允许我设置一个标准的分组矩阵来显示每个文档的静态字段。



但是,我无法将数据表与详细数据{n每个文档的记录}集成在一起。建议?



How can I re-write the rdlc to accommodate such scenario? It should duplicate the entire structure (single fields and matrices) for each document.

I noticed that in this scenario, each table within the dataset has an ID field which help identify/link related records in between datatables.

What I have tried:

I have been looking around the web for insight, but have found nothing relevant so far (not really sure what to look for). 2018/01/09 :: So far, it seems nested matrices only work when all data is contained within the same data source; since I have several data sources, it might not be possible to achieve what I am after.

I tried to use the List control, but so far have been unable to figure out how to work the groups, inner matrices, etc.

Thank you all in advance for your input!.

2018/01/09 16:54 (UTC -04:00) :: After some more research, I came across how to merge data tables (first time). Such approach allowed me to successfully merge most datatable objects into a large on, which in turn, allowed me to set a standard grouped matrix to display each document's static fields.

However, I have not been able to integrate the datatables with detail data {n records for each document}. suggestions?

推荐答案

我在.Net / VB.Net上写了一篇文章,可能有助于将您的数据XML读入.Net模型/转换模型和使用数据模型做你想做的事:



在C#/ VB.Net中读取和编写XML [ ^ ]



你找不到这篇文章通过搜索,因为它专注于树结构化数据,但你的问题听起来像是在寻找类似于树结构数据的东西,所以这个阅读可能有用 - 希望它有所帮助,dirk
I have written an article in .Net/VB.Net that might be useful to read XML your data into a .Net model/convert the model and do what ever you want with the data model:

Reading and Writing XML in C#/VB.Net[^]

You would not find this article via search because its focussed on tree structured data but your question sounds like you are looking at something similar to tree structured data so this read might be useful - hope it helps, dirk


你好每个人,



我能够提出一个有效的解决方案;但是,如果有人有更好的,我们其他人肯定会欣赏它。



案例

从包含1-n个子对象的xml文件中填充rdlc,该对象同时包含静态和动态数据。



结构示例

Hello everyone,

I was able to come up with a working solution; however, if anybody has a better one, the rest of us will certainly appreciate to learn about it.

Case:
Populate a rdlc from a xml file which contains 1-n children objects, which have both static and dynamic data.

Structure Sample
<?xml version="1.0" encoding="ISO-8859-1"?>
<SetDTE>
<DTE version="1.0" > <!-- Children {1-n} (node of interest) -->
<Documento ID="MiPE76266617-720">
    <Encabezado> <!-- static data = single group -->
    	... 
    </Encabezado>
    <Detalle> <!-- dynamic data = 0-n groups -->
	... 
    </Detalle>
    <Detalle>
	...
    </Detalle>
</DTE>
<DTE version="1.0" >
<Documento ID="MiPE76266617-2495">
    <Encabezado> <!-- static data = single group -->
    	...
    </Encabezado>
    <Detalle> <!-- dynamic data = 0-n groups -->
    	...
    </Detalle>
</DTE>
</SetDTE>





起初我尝试使用标准报告填充它,其中包含许多数据表从源xml文件加载的数据集:





At first I tried to populate it using a standard report with the many data tables generated by a dataset loaded from the source xml file:

string xmlSource = System.IO.File.ReadAllText(DTEPath);

DataSet dsXML = new DTE(xmlSource);





其中 DTE 是继承自DataSet的自定义类,它使用其ReadXml方法填充对象。然后我从源中提取所需的表并将它们添加到基础:





Where DTE is a customized class inheriting from DataSet, which makes use of its ReadXml method to populate the object. I then extract the required tables from the source and add them to the base:

base.Tables.Add(dsXML.Tables["Documento"] == null ? new Documento() : dsXML.Tables["Documento"].Copy());





其中 Documento 是一个继承自datatable的自定义类,其目的是提供一致的结构,如果源没有预期的节点。这种方法是有效的,但仅适用于具有感兴趣的单个节点的xml文件。



当面对具有感兴趣的多个节点的xml文件时,标准报告没有削减它。我尝试应用List控件或嵌套矩阵,但不仅需要单个数据源,而且详细行只允许静态数据。



解决方法我找到了

a)通过设置相应的主键将所有静态数据表合并为一个(方法我忽略了并且能够感谢这篇文章)。



b)生成并应用子报告来处理动态区域。



程序

1)生成包含表(tablix)的基本报告,该表必须配置为根据需要包含多个组行。在这种情况下,主要组和儿童组;我扩展了Tablix中剩下的单行/列,以覆盖报告正文的整个区域。



2)已添加到此单个单元格,所有需要的文本框,矩形,线条等分配静态数据;即每组行具有唯一值的数据。 (我添加的矩形是所需子报告的占位符)



3)建立子报告(我需要两个) ,并确保添加所需的输入参数,并过滤它们。在这种情况下,每个子报告都有一个数据源,以及适合其值的表格。



4)添加了子报告 - 报告主要的;每个都在指定的矩形内。



5) 代码



a)托管表格(winform);必须链接处理子报告所需的事件处理程序:





Where Documento is a customized class that inherits from datatable, which purpose is to provide a consistent structure shall the source not have the expected node. This approach is valid, but only for xml files with a single node "of interest".

When faced with xml files with multiple nodes "of interest", the standard report does not cut it. I tried to apply a List control or nested matrices, but not only they require a single datasource, but also, detail rows only allow static data.

The workaround I found was to:
a) Merge all static datatables into a single one by means of setting the respective primary keys (method I ignored and was able to implement thanks to this post).

b) Generate and apply sub-reports to handle the dynamic areas.

Procedure:
1) Generate a base report including a table(tablix), which must be configured to have as many group rows as needed. In this case a main group and a child group; I expanded the single row/column left in the tablix to cover the entire area of the report's body.

2) Added, to this single cell, all required textboxes, rectangles, lines, etc. to allocate the static data; i.e. the data that with unique values per group row. (The rectangles I added are the placeholders for the needed sub-reports)

3) Built the sub-reports (I needed two), and made sure to add the required input parameter, and filter to them. In this case, each sub-report has a data source, and the appropriate table to accommodate its values.

4) Added the sub-reports to the main one; each inside its designated rectangle.

5) The Code:

a) Hosting form (winform); must link the event handler required to process the sub-report(s):

private void FrmMain_Load(object sender, EventArgs e) 
        {
            .... //unrelated code
            RepVwer.LocalReport.SubreportProcessing += new SubreportProcessingEventHandler(SetSubDataSource);

        }



b)主要的空白:获取数据,配置ReportViewer控件,并触发报告的可视化:




b) The main void: which gets the data, configures the ReportViewer control, and triggers the visualization of the report:

private void LoadXmlDTE(string DTEPath)
        {
            try
            {
                DataSet dsXML = new DTE(System.IO.File.ReadAllText(DTEPath));
                
                RepVwer.ProcessingMode = ProcessingMode.Local;
                RepVwer.LocalReport.ReportEmbeddedResource = "DTEViewer.rdlc.EncabezadoDTE.rdlc";
                RepVwer.LocalReport.DataSources.Clear();

                //Datos estáticos por documento
                DataTable auxData = GenerateStaticGlobalData(dsXML);
                RepVwer.LocalReport.DataSources.Add(new ReportDataSource("Global", auxData));
                
                //Datos dinámicos por documento {Sub-Reportes}
                _detalle = dsXML.Tables[6];
                _referencia = dsXML.Tables[7];
                
                this.RepVwer.RefreshReport();

                //... irrelevant code
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, "...", "...", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }



c) GenerateStaticGlobalData方法负责将所有静态数据表合并为一个一,这将是报告的核心数据源:


c) The GenerateStaticGlobalData method is the one in charged of merging all static datatables into a single one, which will be the report's core data source:

private DataTable GenerateStaticGlobalData(DataSet dsXML)
       {
           DataTable auxData = dsXML.Tables[0].Copy();

           auxData.PrimaryKey = new DataColumn[] { auxData.Columns["Documento_Id"] }; //Documento_Id {0}
           dsXML.Tables[1].PrimaryKey = new DataColumn[] { dsXML.Tables[1].Columns["Documento_Id"] };
           auxData.Merge(dsXML.Tables[1]);

           auxData.PrimaryKey = new DataColumn[] { auxData.Columns["Encabezado_Id"] }; //Encabezado_Id {4}
           for (int i = 2; i < 6; i++)
           {
               dsXML.Tables[i].PrimaryKey = new DataColumn[] { dsXML.Tables[i].Columns["Encabezado_Id"] };
               auxData.Merge(dsXML.Tables[i]);
           }

           return auxData; //output
       }



注意:我能够使用代替上面代码中的语句,因为我的DTE类按这样的顺序组织了这些数据表。



d)让我们不要忘记分配事件的事件处理程序子报告的数据来源:


Note: I was able to use a for statement in the above code because my DTE class organized those datatables in such order.

d) Let's not forget the event handler to assign the data source(s) to the sub-report(s):

public void SetSubDataSource(object sender, SubreportProcessingEventArgs e)
       {
           e.DataSources.Add(new ReportDataSource("Detalle", _detalle));
           e.DataSources.Add(new ReportDataSource("Referencias", _referencia));
       }





就是这样;我现在有一份报告(有两个综合的子报告),可以按照客户的预期在屏幕上显示;即每页一个文档,可以根据需要导出或打印。



希望这对其他人有用。



再次感谢所有花时间阅读我的问题的人,现在我自己的答案。



That's it; I now have a report (with two integrated sub-reports), which can be presented on screen as expected by the client; i.e. a document per page, which they can either export or print as desired.

Hopefully, this can be useful for someone else.

Again, thank you all who took the time to read my question, and now my own answer.


这篇关于从XML文件中复用文档rdlc的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆