【问题标题】:Reporting system on Aspose.Word / C#Aspose.Word / C#上的报告系统
【发布时间】:2014-11-25 11:11:28
【问题描述】:
我目前需要一个想法,我正在开发一个软件解决方案,我必须根据 BDD 的信息创建 Words 文档。
关于信息的使用一切都很好,但有一点是最重要的:
在我的 Word 文档中,我使用图章来重复记录信息的表格。其中一列涉及成本,由于我使用的是印章系统,我不知道我的表格在哪里结束,它可能需要 1 页,因为它可能需要 2500 页,但我需要在每个页面的末尾计算写在当前页上的每一行的总数,然后在下一页的开头重写这个总数。所以它会像:
nameOfTheItem1 Cost1
nameOfTheItem2 Cost2
nameOfTheItem3 Cost3
nameOfTheItem4 Cost4
TOTAL PAGE 1 : TotalPage1
总页数1
nameOfTheItem5 Cost5
nameOfTheItem6 Cost6
nameOfTheItem7
Cost7
nameOfTheItem8 Cost8
总页数 2 :
TotalPage2(+TotalPage1)
以及此文档现有的每个页面。
我仍在自己寻找解决方案,每一个帮助都会很棒。
【问题讨论】:
标签:
c#
.net
aspose
aspose.words
【解决方案1】:
可以通过 Aspose.Words 的mail merge 功能来完成。该解决方案与nested mail merge特别相关。
- 您必须在 DataSet 中排列数据,以使报表按照您的要求显示。对于这种情况,安排在 2 个表中。一个是“Page”,另一个是“Item”
- 您的模板文档 (DOCX) 应根据下图定义合并字段。请注意,表格后面有一个分页符。
以下代码将帮助您入门。它当然使用虚拟数据。您可以使用自己的数据进行填充以使其适合您。
使用此代码的 MS Word 模板文档: Download Template
private void yourMethod()
{
string srcDoc = dataDir + "ItemsTemplate.docx";
string dstDoc = dataDir + "ItemsTemplate_Result.docx";
int totalRecords = 10;
int recordsPerPage = 4;
// Prepare some data
DataSet ds = getData(totalRecords, recordsPerPage);
// Prepare the document in Aspose
Aspose.Words.Document doc = new Aspose.Words.Document(srcDoc);
doc.MailMerge.ExecuteWithRegions(ds);
doc.MailMerge.CleanupOptions = Aspose.Words.Reporting.MailMergeCleanupOptions.RemoveEmptyParagraphs;
doc.Save(dstDoc);
Process.Start(dstDoc);
}
private DataSet getData(int totalRecords, int recordsPerPage)
{
DataSet ds = new DataSet("Dataset");
// Add the page table
System.Data.DataTable pageTable = new System.Data.DataTable("Page");
pageTable.Columns.Add("PageNumber");
pageTable.Columns.Add("PageTotal");
pageTable.Columns.Add("PreviousPageTotal");
// Add the item table
System.Data.DataTable itemTable = new System.Data.DataTable("Item");
itemTable.Columns.Add("ID");
itemTable.Columns.Add("Name");
itemTable.Columns.Add("Cost");
itemTable.Columns.Add("PageNumber");
// Add pages
int iRow = 1, iPage = 1;
while (iRow <= totalRecords )
{
DataRow pageRow = pageTable.NewRow();
pageRow["PageNumber"] = iPage;
pageRow["PageTotal"] = 0;
// Add the items in this page
int iRecordsPerPage = 1;
while (iRow <= totalRecords && iRecordsPerPage <= recordsPerPage)
{
DataRow itemRow = itemTable.NewRow();
itemRow["ID"] = iRow;
itemRow["Name"] = "Item " + iRow;
itemRow["Cost"] = iRow;
itemRow["PageNumber"] = iPage;
pageRow["PageTotal"] = int.Parse(pageRow["PageTotal"].ToString()) + int.Parse(itemRow["Cost"].ToString());
itemTable.Rows.Add(itemRow);
iRow++;
iRecordsPerPage++;
}
pageTable.Rows.Add(pageRow);
// Previous page total
if (iPage == 1)
pageRow["PreviousPageTotal"] = 0; // Always 0 for first page
else
pageRow["PreviousPageTotal"] = pageTable.Rows[iPage - 2]["PageTotal"]; // Get total of previous page
iPage++;
}
ds.Tables.Add(pageTable);
ds.Tables.Add(itemTable);
// We must have relationship for Aspose mail merge to work correctly
ds.Relations.Add(pageTable.Columns["PageNumber"], itemTable.Columns["PageNumber"]);
return ds;
}
尝试更改 totalRecords 和 recordsPerPage 变量的值,您将看到相应地按页面排列的数据。请确保将 recordsPerPage 值保持在较低水平,以使其不超过单页。
我是 Aspose 的开发布道者。
【解决方案2】:
我正在将数据导出到现有的 .dotx 字模板
但是,即使我在代码中添加了目录,最终报告也没有显示目录。
我的代码如下
public void ExportToWordUsingTemplate()
{
Aspose.Words.Document doc1 = new Aspose.Words.Document(@"E:/excel/HOVEDMAL Prognoserapporter 2.dotx");
DocumentBuilder docBuilder1 = new DocumentBuilder(doc1);
SkinAPI.ReportAPISoapClient svc = new SkinAPI.ReportAPISoapClient();
SkinAPI.GetReportContextResult myReportContext = svc.GetReportContext(1);
docBuilder1.InsertHtml("<h1 align='left'>" + myReportContext[0].MainReportName + "</h1>");
docBuilder1.InsertTableOfContents("\\o \"1-3\" \\h \\z \\u");
//for (int i = 0; i < myReportContext.Count - 2; i++)
for (int i = 0; i < 5; i++)
{
SkinAPI.GetReportElementGraphDataResult myElementGraphData = svc.GetReportElementGraphData(myReportContext[i].ReportId, myReportContext[i].ElementId);
SkinAPI.GetReportElementDataResult myElementData = svc.GetReportElementData(myReportContext[i].ReportId, myReportContext[i].ElementId, 0, 0, 0); // Three last parameters set to 0, used when fetching drilldown data for tables that support it
docBuilder1.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading1;
docBuilder1.Writeln(myReportContext[i].ElementHeader);
docBuilder1.ParagraphFormat.StyleIdentifier = StyleIdentifier.BodyText;
// Is there a graph for this element, and has it a datasource other than the main data source as fetched above?
if (myReportContext[i].HasGraph && myReportContext[i].SeparateGraphDataSource)
{
// Is there a text part for this element
if (myReportContext[i].HasText)
{
// The returned string will contain a HTML text.
// Note that the text is connected to a TileId, not an ElementId, meening the text might have been fetched before.
string myElementHTMLDescription = svc.GetReportText(myReportContext[i].TileId);
docBuilder1.InsertHtml(myElementHTMLDescription);
}
}
docBuilder1.InsertBreak(BreakType.PageBreak);
}
doc1.Save(@"E:/excel/HOVEDMAL Prognoserapporter 2_Report.doc");
}