<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ジャナ・ビジネス・コンサルティング &#187; Spreadsheet</title>
	<atom:link href="http://www.janabiz.com/category/spreadsheet/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.janabiz.com</link>
	<description>新聞、電子出版、Webシステム開発 SAP ERP開発 人材派遣 Java Android プログラマ学校</description>
	<lastBuildDate>Sat, 04 Mar 2023 03:22:06 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>OpenXML Spreadsheet, how to copy and insert specified rows</title>
		<link>http://www.janabiz.com/openxml-copy-spreadsheet-rows/</link>
		<comments>http://www.janabiz.com/openxml-copy-spreadsheet-rows/#comments</comments>
		<pubDate>Mon, 13 May 2013 09:44:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Excel]]></category>
		<category><![CDATA[Spreadsheet]]></category>
		<category><![CDATA[OpenXML]]></category>

		<guid isPermaLink="false">http://new.janabiz.com/?p=371</guid>
		<description><![CDATA[<p>We usually use OpenXML spreadsheet to create excel document and report. For some document and report, sometimes we hope copy and insert some rows or columns automatically. For example , we want to output a list data into excel worksheet whose element has 3 formatted rows including some merge cells etc. If list&#8217;s size is 10, we hope copy 3 formatted rows of first element 10 times and insert copied rows below the first element rows automatically. In OpenXML spreadsheet, when you copy some rows and insert copied rows into destination, there are many works to do. First, in the copied rows, maybe there are some merge cells, data validate &#8230; <a href="http://www.janabiz.com/openxml-copy-spreadsheet-rows/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://www.janabiz.com/openxml-copy-spreadsheet-rows/">OpenXML Spreadsheet, how to copy and insert specified rows</a> appeared first on <a href="http://www.janabiz.com">ジャナ・ビジネス・コンサルティング</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>We usually use OpenXML spreadsheet to create excel document and report. For some document and report, sometimes we hope copy and insert some rows or columns automatically. For example , we want to output a list data into excel worksheet whose element has 3 formatted rows including some merge cells etc. If list&#8217;s size is 10, we hope copy 3 formatted rows of first element 10 times and insert copied rows below the first element rows automatically. </p>
<p>In OpenXML spreadsheet, when you copy some rows and insert copied rows into destination, there are many works to do. First, in the copied rows, maybe there are some merge cells, data validate list ( pull down cells), formulas, drawings, charts. You must change the row&#8217;s index number to the inserted rows. Then the row&#8217;s index number for objects below in the destination must be changed. These objects include normal cells, merge cells, data validate list, formulas, drawings, charts etc.</p>
<p>The following is part of code to explain how to implement copy and insert. About the complete examples, please <a href="/dl?pcode=200002" alt="OpenXML spreadsheet | Excel solution | Excel Report | Excelソリューション">Download ExcelTDF Package</a> </p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%">        <span style="color: #008000">/// &lt;summary&gt;                                                      </span>
        <span style="color: #008000">/// Copy the part of rows from srcRowFrom to srcRowTo between srcColFrom and srcColTo. </span>
        <span style="color: #008000">/// The row index, whose  column is between column srcColFrom and srcColTo, and whose</span>
        <span style="color: #008000">/// row is below the destRowFrom, will be changed after cloned cells added into worksheet.</span>
        <span style="color: #008000">/// &lt;/summary&gt;</span>
        <span style="color: #008000">/// &lt;param name=&quot;workbookPart&quot;&gt;&lt;see cref=&quot;WorkbookPart&quot;/&gt;&lt;/param&gt;</span>
        <span style="color: #008000">/// &lt;param name=&quot;sheetIndex&quot;&gt;worksheet index&lt;/param&gt;</span>
        <span style="color: #008000">/// &lt;param name=&quot;srcRowFrom&quot;&gt;source from row index&lt;/param&gt;</span>
        <span style="color: #008000">/// &lt;param name=&quot;srcRowTo&quot;&gt;source to row index&lt;/param&gt;</span>
        <span style="color: #008000">/// &lt;param name=&quot;destRowFrom&quot;&gt;destination from row index&lt;/param&gt;</span>
        <span style="color: #008000">/// &lt;param name=&quot;copyTimes&quot;&gt;the times to be copied&lt;/param&gt;</span>
        <span style="color: #008000">/// &lt;param name=&quot;srcColFrom&quot;&gt;limitation of column left&lt;/param&gt;</span>
        <span style="color: #008000">/// &lt;param name=&quot;srcColTo&quot;&gt;limitation of column right&lt;/param&gt;</span>
        <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> CopyRowRange(WorkbookPart workbookPart, <span style="color: #2b91af">int</span> sheetIndex,
            <span style="color: #2b91af">int</span> srcRowFrom, <span style="color: #2b91af">int</span> srcRowTo, <span style="color: #2b91af">int</span> destRowFrom, <span style="color: #2b91af">int</span> copyTimes, <span style="color: #2b91af">int</span> srcColFrom, <span style="color: #2b91af">int</span> srcColTo)
        {
            <span style="color: #008000">//only support copy down </span>
            <span style="color: #0000ff">if</span> (copyTimes &lt;= 0 || srcRowTo &lt; srcRowFrom || destRowFrom &lt; srcRowFrom) <span style="color: #0000ff">return</span>;
            <span style="color: #2b91af">int</span> destRowFromBase = destRowFrom;

            <span style="color: #008000">//Get the source sheet to be copied</span>
            WorksheetPart worksheetPart = GetWorksheetPart(workbookPart, sheetIndex);
            SheetData sheetData = worksheetPart.Worksheet.GetFirstChild&lt;SheetData&gt;();

            <span style="color: #008000">//get cells to be cloned according to the specified rows and columns</span>
            IList&lt;Cell&gt; cells = sheetData.Descendants&lt;Cell&gt;().Where(c =&gt;
                GetRowIndex(c.CellReference) &gt;= srcRowFrom &amp;&amp;
                GetRowIndex(c.CellReference) &lt;= srcRowTo &amp;&amp;
                GetCellColIndex(c.CellReference) &gt;= srcColFrom &amp;&amp;
                GetCellColIndex(c.CellReference) &lt;= srcColTo).ToList&lt;Cell&gt;();

            <span style="color: #008000">//no cells to be cloned</span>
            <span style="color: #0000ff">if</span> (cells.Count() == 0) <span style="color: #0000ff">return</span>;


            <span style="color: #008000">//after cloned, the index of rows from destRowFrom should be changed</span>
            <span style="color: #008000">//diff rows between srcColFrom and srcColTo</span>
            <span style="color: #2b91af">int</span> copiedRowCount = srcRowTo - srcRowFrom + 1;

            <span style="color: #008000">//move row index between srcColFrom and srcColTo that the row index greater or equal to </span>
            <span style="color: #008000">//destRowFrom</span>
            MoveRowIndex(workbookPart, sheetIndex, destRowFrom - 1, copiedRowCount * copyTimes, srcColFrom, srcColTo);

            <span style="color: #008000">//temporary array of changed row index</span>
            IList&lt;<span style="color: #2b91af">int</span>&gt; changeRowIndexs = <span style="color: #0000ff">new</span> List&lt;<span style="color: #2b91af">int</span>&gt;();

            <span style="color: #008000">//cloned cells, row index/cells</span>
            IDictionary&lt;<span style="color: #2b91af">int</span>, IList&lt;Cell&gt;&gt; clonedCells = <span style="color: #0000ff">null</span>;

            <span style="color: #008000">//formula cells in cloned cells</span>
            IList&lt;Cell&gt; formulaCells = <span style="color: #0000ff">new</span> List&lt;Cell&gt;();

            <span style="color: #008000">//cloned related rows for speed</span>
            IList&lt;Row&gt; cloneRelatedRows = <span style="color: #0000ff">new</span> List&lt;Row&gt;();

            <span style="color: #0000ff">for</span> (<span style="color: #2b91af">int</span> i = 0; i &lt; copyTimes; i++)
            {
                <span style="color: #008000">//next copy col index</span>
                destRowFrom = destRowFromBase + copiedRowCount * i;
                <span style="color: #008000">// changed column index</span>
                <span style="color: #2b91af">int</span> changedRows = destRowFrom - srcRowFrom;

                <span style="color: #008000">//add change column index to list</span>
                changeRowIndexs.Add(changedRows);
                <span style="color: #008000">//clear formula cells</span>
                formulaCells.Clear();

                <span style="color: #008000">//1: cloned cells, row index/cell list </span>
                clonedCells = <span style="color: #0000ff">new</span> Dictionary&lt;<span style="color: #2b91af">int</span>, IList&lt;Cell&gt;&gt;();

                <span style="color: #0000ff">foreach</span> (Cell cell <span style="color: #0000ff">in</span> cells)
                {
                    Cell newCell = (Cell)cell.CloneNode(<span style="color: #0000ff">true</span>);
                    <span style="color: #2b91af">int</span>[] indexs = GetCellIndex(cell.CellReference);
                    <span style="color: #008000">//change row index of cloned cell</span>
                    <span style="color: #2b91af">int</span> rowIndex = indexs[1] + changedRows;
                    newCell.CellReference = GetColumnName(cell.CellReference) + rowIndex.ToString();

                    IList&lt;Cell&gt; rowCells = <span style="color: #0000ff">null</span>;
                    <span style="color: #0000ff">if</span> (clonedCells.ContainsKey(rowIndex))
                        rowCells = clonedCells[rowIndex];
                    <span style="color: #0000ff">else</span>
                    {
                        rowCells = <span style="color: #0000ff">new</span> List&lt;Cell&gt;();
                        clonedCells.Add(rowIndex, rowCells);
                    }
                    rowCells.Add(newCell);

                    <span style="color: #008000">//if is formula cell</span>
                    <span style="color: #0000ff">if</span> (newCell.CellFormula != <span style="color: #0000ff">null</span> &amp;&amp; newCell.CellFormula.Text.Length &gt; 0)
                    {
                        formulaCells.Add(newCell);
                    }
                }

                <span style="color: #008000">//add cloned cell into row</span>
                <span style="color: #0000ff">foreach</span> (<span style="color: #2b91af">int</span> rowIndex <span style="color: #0000ff">in</span> clonedCells.Keys)
                {
                    Row row = sheetData.Elements&lt;Row&gt;().Where(r =&gt; r.RowIndex == rowIndex).FirstOrDefault();
                    <span style="color: #008000">//if no this row </span>
                    <span style="color: #0000ff">if</span> (row == <span style="color: #0000ff">null</span>)
                    {
                        row = <span style="color: #0000ff">new</span> Row() { RowIndex = (<span style="color: #2b91af">uint</span>)rowIndex };
                        <span style="color: #008000">//find insert position</span>
                        Row refRow = sheetData.Elements&lt;Row&gt;().Where(r =&gt; r.RowIndex &gt; rowIndex).OrderBy(r =&gt; r.RowIndex).FirstOrDefault();
                        <span style="color: #0000ff">if</span> (refRow == <span style="color: #0000ff">null</span>)
                            sheetData.AppendChild&lt;Row&gt;(row);
                        <span style="color: #0000ff">else</span>
                            sheetData.InsertBefore&lt;Row&gt;(row, refRow);
                    }
                    row.Append(clonedCells[rowIndex].ToArray());

                    <span style="color: #008000">//add into clone related rows</span>
                    cloneRelatedRows.Add(row);
                }

                <span style="color: #008000">//2: processing copied range&#39;s formula </span>
                ChangeFormulaRowNumber(formulaCells, changedRows);

                <span style="color: #008000">//3: copy drawings in range</span>
                CopyDrawingsInRange(worksheetPart, srcRowFrom, srcRowTo, srcColFrom, srcColTo, destRowFrom, -1);
            }

            <span style="color: #008000"></span>
            <span style="color: #0000ff">foreach</span> (Row row <span style="color: #0000ff">in</span> cloneRelatedRows)
            {
                <span style="color: #008000">// sort by column name</span>
                IList&lt;Cell&gt; cs = row.Elements&lt;Cell&gt;().OrderBy(c =&gt; GetCellColIndex(c.CellReference.Value)).ToList&lt;Cell&gt;();
                row.RemoveAllChildren();
                row.Append(cs.ToArray());
            }
            
            <span style="color: #008000">//2: process merge cell in cloned rows</span>
            MergeCells mcells = worksheetPart.Worksheet.GetFirstChild&lt;MergeCells&gt;();
            <span style="color: #0000ff">if</span> (mcells != <span style="color: #0000ff">null</span>)
            {
                IList&lt;MergeCell&gt; newMergeCells = <span style="color: #0000ff">new</span> List&lt;MergeCell&gt;();
                IEnumerable&lt;MergeCell&gt; clonedMergeCells = mcells.Elements&lt;MergeCell&gt;().
                    Where(m =&gt; MergeCellInRange(m, srcRowFrom, srcRowTo, srcColFrom, srcColTo)).ToList&lt;MergeCell&gt;();
                <span style="color: #0000ff">foreach</span> (MergeCell cmCell <span style="color: #0000ff">in</span> clonedMergeCells)
                {
                    <span style="color: #0000ff">foreach</span> (<span style="color: #2b91af">int</span> changedRows <span style="color: #0000ff">in</span> changeRowIndexs)
                    {
                        MergeCell newMergeCell = CreateChangedRowMergeCell(cmCell, changedRows);
                        newMergeCells.Add(newMergeCell);
                    }
                }
                <span style="color: #2b91af">uint</span> count = mcells.Count.Value;
                mcells.Count = <span style="color: #0000ff">new</span> UInt32Value(count + (<span style="color: #2b91af">uint</span>)newMergeCells.Count);
                mcells.Append(newMergeCells.ToArray());
            }

            <span style="color: #008000">//3: process datavalidate list</span>
            IDictionary&lt;<span style="color: #2b91af">string</span>, DataValidation&gt; validates = GetDataValidatesInRange(worksheetPart, srcRowFrom, srcRowTo, srcColFrom, srcColTo);
            <span style="color: #0000ff">foreach</span> (<span style="color: #2b91af">string</span> cellname <span style="color: #0000ff">in</span> validates.Keys)
            {
                <span style="color: #0000ff">foreach</span> (<span style="color: #2b91af">int</span> changedRows <span style="color: #0000ff">in</span> changeRowIndexs)
                {
                    AddDataValidateRefItemOfChangedRow(cellname, changedRows, validates[cellname]);
                }
            }
        }
</pre>
</div>
<p>The post <a href="http://www.janabiz.com/openxml-copy-spreadsheet-rows/">OpenXML Spreadsheet, how to copy and insert specified rows</a> appeared first on <a href="http://www.janabiz.com">ジャナ・ビジネス・コンサルティング</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.janabiz.com/openxml-copy-spreadsheet-rows/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ExcelTDF, create excel report by metadata quickly</title>
		<link>http://www.janabiz.com/exceltdf-fast-create-excel-report-by-metadata/</link>
		<comments>http://www.janabiz.com/exceltdf-fast-create-excel-report-by-metadata/#comments</comments>
		<pubDate>Mon, 13 May 2013 09:37:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Excel]]></category>
		<category><![CDATA[Spreadsheet]]></category>

		<guid isPermaLink="false">http://new.janabiz.com/?p=366</guid>
		<description><![CDATA[<p>ExcelTDF provides very simple way to create complicated excel report. ExcelTDF is able to process row range, column range, block range and complicated range which including some child ranges such as list, list clone range, list-in-list range etc. You can define these ranges by Metadata. Let us show some examples. Download Metadata examples FastExcelReport 1. Create a console application project: assume it is S:\project\FastExcelReport. 2. Set ExcelTDF configuration as following. 2.1. Add ExcelTDF repository configuration file Repository.config into your project. The content of Repository.config is shown as following &#60;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34; ?&#62; &#60;objects xmlns=&#34;http://www.springframework.net&#34;&#62; &#60;object id=&#34;mydemo&#34; type=&#34;JanaBiz.OpenXml.Repository.FileSystemRepositoryManager, JanaBiz.OpenXml&#34;&#62; &#60;property name=&#34;RepositoryName&#34; value=&#34;mydemo&#34;/&#62; &#60;property name=&#34;RepositoryUri&#34; value=&#34;../Templates&#34;/&#62; &#60;/object&#62; &#60;/objects&#62; By the above configuration, &#8230; <a href="http://www.janabiz.com/exceltdf-fast-create-excel-report-by-metadata/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://www.janabiz.com/exceltdf-fast-create-excel-report-by-metadata/">ExcelTDF, create excel report by metadata quickly</a> appeared first on <a href="http://www.janabiz.com">ジャナ・ビジネス・コンサルティング</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>ExcelTDF provides very simple way to create complicated excel report. ExcelTDF is able to process row range, column range, block range and complicated range which including some child ranges such as list, list clone range, list-in-list range etc. You can define these ranges by Metadata. Let us show some examples.</p>
<p>Download Metadata examples <a href='/wp-content/uploads/FastExcelReport.zip'>FastExcelReport</a></p>
<p>1. Create a console application project: assume it is S:\project\FastExcelReport.</p>
<p>2. Set ExcelTDF configuration as following.</p>
<p>2.1. Add ExcelTDF repository configuration file <strong>Repository.config</strong> into your project. The content of Repository.config is shown as following</p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%">&lt;?xml version=<span style="color: #a31515">&quot;1.0&quot;</span> encoding=<span style="color: #a31515">&quot;utf-8&quot;</span> ?&gt;
&lt;objects xmlns=<span style="color: #a31515">&quot;http://www.springframework.net&quot;</span>&gt;
  
  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;mydemo&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.Repository.FileSystemRepositoryManager, JanaBiz.OpenXml&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RepositoryName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;mydemo&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;RepositoryUri&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;../Templates&quot;</span>/&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;
&lt;/objects&gt;
</pre>
</div>
<p>By the above configuration, your template and template range configuration file are placed in the directory of ../Templates/mydemo (RepositoryName) which is related the executable directory bin.  The template file name *.xlsx and template range configuration file *.xml must have the same name, and this name is also their Template ID. ExcelTDF will search all templates and template range configuration files in root repository and subdirectories. <strong>When you use metadata, no template range configuration file is needed</strong></p>
<p>3. Design your template, here named MetadataTest.xslx, and save it into the specified path of repository configured above S:\project\FastExcelReport\Templates\mydemo\MetadataTest.xlsx </p>
<p><a href="/wp-content/uploads/metadatatest.png"><img src="/wp-content/uploads/metadatatest.png" alt="ExcelTDF .NET metadata | Excel report" title="ExcelTDF .NET metadata | Excel report" width="1280" height="994" class="aligncenter size-full wp-image-1265" /></a></p>
<p>4. Create your data model according to the template ranges.</p>
<p>4.1. Add reference assemblies<br />
&nbsp;&nbsp;&nbsp;&nbsp; . JanaBiz.OpenXml.dll<br />
&nbsp;&nbsp;&nbsp;&nbsp; . DocumentFormat.OpenXml.dll<br />
&nbsp;&nbsp;&nbsp;&nbsp; . log4net.dll<br />
&nbsp;&nbsp;&nbsp;&nbsp; . Spring.Core.dll</p>
<p>4.2. Create data model class as following</p>
<p><!-- HTML generated using hilite.me -->
<div class="div-example">
<pre style="margin: 0; line-height: 125%"><span style="color: #0000ff">using</span> System;
<span style="color: #0000ff">using</span> System.Collections.Generic;
<span style="color: #0000ff">using</span> System.Linq;
<span style="color: #0000ff">using</span> System.Text;
<span style="color: #0000ff">using</span> JanaBiz.OpenXml;

<span style="color: #008000">//define class for each range </span>
<span style="color: #0000ff">namespace</span> FastExcelReport
{
    <span style="color: #008000">/// &lt;summary&gt;</span>
    <span style="color: #008000">/// Assume A-Range is root range</span>
    <span style="color: #008000">/// &lt;/summary&gt;</span>
    [ExcelRange(&quot;A-Range&quot;, &quot;A1&quot;, &quot;AF40&quot;, &quot;BlockRangeService&quot;)]
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">MetadataTestDataModel</span>
    {
        <span style="color: #0000ff">public</span> MetadataTestDataModel()
        {
            <span style="color: #0000ff">for</span> (<span style="color: #2b91af">int</span> i = 0; i &lt; 4; i++)
            {
                cRangeList.Add(<span style="color: #0000ff">new</span> CRange()
                {
                    Item1 = (i + 1) * 30
                });
            }
        }


        [Excel(&quot;AItem1&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> Item1 = <span style="color: #a31515">&quot;Item1 in range A&quot;</span>;

        [Excel(&quot;AItem3&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> Item3 = <span style="color: #a31515">&quot;Item3 in range A&quot;</span>;

        [ExcelRange(&quot;B-Range&quot;, &quot;G11&quot;, &quot;Q32&quot;, &quot;BlockRangeService&quot;)]
        <span style="color: #0000ff">public</span> BRange bRange = <span style="color: #0000ff">new</span> BRange();


        <span style="color: #008000">/// &lt;summary&gt;</span>
        <span style="color: #008000">/// The range is defined by first element area</span>
        <span style="color: #008000">/// &lt;/summary&gt;</span>
        [ExcelRange(&quot;C-Range&quot;, &quot;T4&quot;, &quot;AE5&quot;, &quot;RowListRangeService&quot;, PageSize = 4)]
        <span style="color: #0000ff">public</span> IList&lt;CRange&gt; cRangeList = <span style="color: #0000ff">new</span> List&lt;CRange&gt;();            

        [ExcelRange(&quot;D-Range&quot;, &quot;B35&quot;, &quot;AF40&quot;, &quot;BlockRangeService&quot;)]
        <span style="color: #0000ff">public</span> DRange dRange = <span style="color: #0000ff">new</span> DRange();
    }

    <span style="color: #008000">/// &lt;summary&gt;</span>
    <span style="color: #008000">/// The data model of B-Range</span>
    <span style="color: #008000">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">BRange</span>
    {
        [Excel(&quot;BItem1&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> Item1 = <span style="color: #a31515">&quot;Item1 in range B&quot;</span>;

        [Excel(&quot;BItem2&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> Item2 = <span style="color: #a31515">&quot;Item2 in range B&quot;</span>;

    }

    <span style="color: #008000">/// &lt;summary&gt;</span>
    <span style="color: #008000">/// The data model of C-Range</span>
    <span style="color: #008000">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">CRange</span>
    {
        [Excel(&quot;CItem1&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">int</span> Item1 = 300;

        [Excel(&quot;CItem2&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">double</span> Item2;  <span style="color: #008000">//save the result of sum</span>

        [Excel(&quot;CItem3&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">double</span> Item3 = 12.5;

        [Excel(&quot;CItem4&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> Item4 = <span style="color: #a31515">&quot;Item4 in range C&quot;</span>;

        [Excel(&quot;CItem6&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">long</span> Item6 = 1290865;
    }


    <span style="color: #008000">/// &lt;summary&gt;</span>
    <span style="color: #008000">/// The data model of D-Range</span>
    <span style="color: #008000">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">DRange</span>
    {
        <span style="color: #0000ff">private</span> <span style="color: #2b91af">string</span> item1 = <span style="color: #a31515">&quot;Item1 in range D&quot;</span>;


        [Excel(&quot;DItem1&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> Item1
        {
            <span style="color: #0000ff">get</span> { <span style="color: #0000ff">return</span> item1; }
            <span style="color: #0000ff">set</span> { item1 = <span style="color: #0000ff">value</span>; }
        }
    }    
}
</pre>
</div>
<p><br/></p>
<p>5. Add following template processing code into your program. That is over</p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%"><span style="color: #0000ff">using</span> System;
<span style="color: #0000ff">using</span> System.Collections.Generic;
<span style="color: #0000ff">using</span> System.Linq;
<span style="color: #0000ff">using</span> System.Text;
<span style="color: #0000ff">using</span> System.IO;
<span style="color: #0000ff">using</span> System.Reflection;

<span style="color: #0000ff">using</span> JanaBiz.OpenXml.Template;
<span style="color: #0000ff">using</span> JanaBiz.OpenXml.Handler;
<span style="color: #0000ff">using</span> JanaBiz.OpenXml.Data;
<span style="color: #0000ff">using</span> JanaBiz.OpenXml.Context;
<span style="color: #0000ff">using</span> JanaBiz.OpenXml.Repository;


<span style="color: #008000">//load configuration of repository</span>
<strong>[assembly: RegisterRepository(&quot;FastExcelReport.Repository.config&quot;)]</strong>

<span style="color: #0000ff">namespace</span> FastExcelReport
{
    <span style="color: #0000ff">class</span> <span style="color: #2b91af">Program</span>
    {
        <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> Main(<span style="color: #2b91af">string</span>[] args)
        {

<span style="color: #008000">//            OpenXmlContext.RegisterRepository(&quot;FastExcelReport.Repository.config&quot;);</span>

            <span style="color: #008000">//create your handler </span>
            IOpenXmlHandler handler = <span style="color: #0000ff">new</span> OpenXmlHandler();

            <span style="color: #008000">//tell ExcelTDF which ITemplateService is used to </span>
            <span style="color: #008000">//get template file and template range configuration</span>
            handler.GetTemplateService&lt;LocalTemplateService&gt;();

            <span style="color: #008000">//set template id to identify which template is used</span>
            handler.TemplateId = <span style="color: #a31515">&quot;MetadataTest&quot;</span>;

            <span style="color: #008000">//tell ExcelTDF which IDataProviderManager and </span>
            <span style="color: #008000">//what data provider is used            </span>
            handler.DataProviderManager = <span style="color: #0000ff">new</span> DataModelProviderManager(
                <span style="color: #0000ff">new</span> MetadataTestDataModel());

            <span style="color: #008000">//parse your template </span>
           <strong> handler.ParseTemplate(<span style="color: #0000ff">false</span>);</strong>

            <span style="color: #008000">//parse your data </span>
            handler.ParseWorkbook(<span style="color: #0000ff">null</span>);

            <span style="color: #008000">//PLEASE REPLACE with your file stream to get result document</span>
            FileStream fs = <span style="color: #0000ff">new</span> FileStream(<span style="color: #a31515">@&quot;c:\temp\metadatatest-result.xlsx&quot;</span>, FileMode.Create);           

            <span style="color: #008000">//write parsed document into response stream</span>
            handler.WriteParsedDocument(fs);
            fs.Close();

            <span style="color: #008000">//release some resource</span>
            handler.Close();
        }
    }
}
</pre>
</div>
<p>
The line of </p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%">[assembly: RegisterRepository(&quot;FastExcelReport.Repository.config&quot;)]
</pre>
</div>
<p>is used to load Repository.config file.</p>
<p>The result of pecessed template is show as following.</p>
<p><a href="/wp-content/uploads/metadatatest-result.png"><img src="/wp-content/uploads/metadatatest-result.png" alt="ExcelTDF .NET metadata | fast Excel report" title="ExcelTDF .NET metadata | fast Excel report-result" width="1280" height="994" class="aligncenter size-full wp-image-1266" /></a></p>
<p>The post <a href="http://www.janabiz.com/exceltdf-fast-create-excel-report-by-metadata/">ExcelTDF, create excel report by metadata quickly</a> appeared first on <a href="http://www.janabiz.com">ジャナ・ビジネス・コンサルティング</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.janabiz.com/exceltdf-fast-create-excel-report-by-metadata/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ExcelTDF Package Introduction</title>
		<link>http://www.janabiz.com/exceltdf/</link>
		<comments>http://www.janabiz.com/exceltdf/#comments</comments>
		<pubDate>Mon, 13 May 2013 09:28:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Excel]]></category>
		<category><![CDATA[Products]]></category>
		<category><![CDATA[Spreadsheet]]></category>

		<guid isPermaLink="false">http://new.janabiz.com/?p=364</guid>
		<description><![CDATA[<p>1. What is ExcelTDF 2. Introduction 3. Overview 3.1. How to use ExcelTDF in your solution As the following diagram shows, ExcelTDF is able to run at server-side, client-side and client-only. The interface and usage is the same wherever the ExcelTDF is running. For the both server-side and client-side, the templates of excel are managed on the server. The difference between server-side and client-side is that client-side provides auto saving functionality. 3.2. ExcelTDF Core classes ExcelTDF does almost of work for you by some core classes. Excel2007TemplateParser and Excel2007DataParser are the two of these classes. But the convenient way for you is using implementation classes of IExcelHandler or IOpenXmlHandler interface &#8230; <a href="http://www.janabiz.com/exceltdf/">Continue reading <span class="meta-nav">&#8594;</span></a></p><p>The post <a href="http://www.janabiz.com/exceltdf/">ExcelTDF Package Introduction</a> appeared first on <a href="http://www.janabiz.com">ジャナ・ビジネス・コンサルティング</a>.</p>]]></description>
				<content:encoded><![CDATA[<p><strong><a href="/exceltdf-package">1. What is ExcelTDF </a></strong><br />
<strong><a href="/exceltdf-package">2. Introduction</a></strong></p>
<p><strong><a name="3">3. Overview</a></strong></p>
<p><strong>3.1. <a name="3.1">How to use ExcelTDF in your solution</a></strong><br />
As the following diagram shows, ExcelTDF is able to run at server-side, client-side and client-only. The interface and usage is the same wherever the ExcelTDF is running. For the both server-side and client-side, the templates of excel are managed on the server. The difference between server-side and client-side is that client-side provides auto saving functionality.<br />
<a href="/wp-content/uploads/2010/09/aspnet-diagram.png"><img class="aligncenter size-large wp-image-804" title="aspnet-diagram" src="/wp-content/uploads/2010/09/aspnet-diagram-1024x594.png" alt="" width="640" height="371" /></a><br />
<a href="/wp-content/uploads/2010/09/clientside-diagram.png"><img class="aligncenter size-large wp-image-805" title="clientside-diagram" src="/wp-content/uploads/2010/09/clientside-diagram-1024x625.png" alt="" width="640" height="390" /></a></p>
<p><strong>3.2. <a name="3.2">ExcelTDF Core classes</a></strong><br />
ExcelTDF does almost of work for you by some core classes. <strong>Excel2007TemplateParser </strong>and <strong>Excel2007DataParser </strong> are the two of these classes. But the convenient way for you is using implementation classes of <strong>IExcelHandler </strong>or <strong>IOpenXmlHandler </strong>interface named <strong>ExcelHandler</strong>, <strong>OpenXmlHandler</strong>. Excel2007TemplateParser, as the name of class, analyzes the template file and load the <strong>template range</strong> configuration file. After template is analyzed, template parser will know the mapping relationship of variables/cells and <strong>template range</strong> tree. Excel2007DataParser analyzes your data class structure and its meta data or SQL data. Metadata named <strong>ExcelRange</strong> and <strong>ExcelAttribute</strong> defines range information and Excel cell variable information. After data is analyzed, Excel2007DataParser will know the data/variable mapping relationship and get <strong>ExcelRange</strong>&#8216;s tree structure that is used to used to  determine how to process template.</p>
<p><a href="/wp-content/uploads/2010/12/ExcelTDF-diagram.png"><img class="aligncenter size-large wp-image-761" title="ExcelTDF-diagram" src="/wp-content/uploads/2010/12/ExcelTDF-diagram-1024x612.png" alt="" width="640" height="382" /></a></p>
<p>	<strong>3.3. <a name="3.3">How to get ExcelTDF work</a></strong><br />
In order to let ExcelTDF work, there are fourth steps to do, the first two steps is only needed to do one time.<br />
	<strong> . Set Configuration</strong><br />
	<strong> . Creating template file by Excel 2007 above and creating template range configuration file. If you use Metadata to define all range information, this step can be omitted</strong><br />
	<strong> . Creating IDataProvider class or Data Model class to get data</strong><br />
	<strong> . Download or open your parsed document or report</strong></p>
<p><strong>3.4. <a name="3.4">Set Configuration</a></strong><br />
When you use ExcelTDF to process template, you should tell ExcelTDF how to get template files and template range configuration files. Your template files and template range configuration files maybe saved as files in specified directory or saved in database or gotten from service.</p>
<p><strong>3.4.1. <a name="3.4.1">Manage templates by files</a></strong><br />
Your template excel file and template range configuration file can be managed on server by files. In ExcelTDF we call it repository. Typically your configuration file is named as Repository.config. It is loaded by ExcelTDF when application starting.<br />
The following is the content of Repository.config. You can add more repositories in this file.</p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%">&lt;?xml version=<span style="color: #a31515">&quot;1.0&quot;</span> encoding=<span style="color: #a31515">&quot;utf-8&quot;</span> ?&gt;
&lt;objects xmlns=<span style="color: #a31515">&quot;http://www.springframework.net&quot;</span>&gt;
  
  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;mydemo&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.Repository.FileSystemRepositoryManager, JanaBiz.OpenXml&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RepositoryName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;myrepository&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;RepositoryUri&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;../../Templates&quot;</span>/&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

&lt;/objects&gt;
</pre>
</div>
<p>On the above, the root repository directory is ../../Templates/myrepository. This is relative path to the executable dll. Certainlly, it is can be any full path. It is also be able to database connection string or others for RepositoryUri.</p>
<p>Usually you can use following two ways to load Repository.config when application starting.</p>
<p>a).  For console application or Windows form application</p>
<div  class="div-example">
<pre style="margin: 0; line-height: 125%">[assembly: RegisterRepository(&quot;your_namespace.Repository.config&quot;)]
</pre>
</div>
<p>b). For all type of application </p>
<div  class="div-example">
<pre style="margin: 0; line-height: 125%">            OpenXmlContext.RegisterRepository(<span style="color: #a31515">&quot;your_namespace.Repository.config&quot;</span>);
</pre>
</div>
<p><br/><br/></p>
<p><strong>Refresh your repository</strong><br />
If your template range configuration file is changed or you added, removed some lines in template.xml and resource.xml, you must refresh context to load new configuration information. ExcelTDF provides a method in class OpenXmlContext to reload repositories.</p>
<p><strong>3.4.2. <a name="3.4.2">Manage templates by database</a></strong><br />
If you get template file and template range configuration file from database or other stream resource, you don&#8217;t have to set repository information . The resource handler&#8217;s protocol named &#8220;memory&#8221; will load your template file, template range configuration file into context. In order to do this work, you must create a class that implements the interface <strong>ITemplateService</strong>. By following code, you can set your database template service which implements ITemplateService. This tells ExcelTDF MyDatabaseTemplateService is used to get template file and template range configuration, similar to handler.GetTemplateService(&#8220;myconfig&#8221;) which use LocalTemplateService to load template files in the repository. There are no access limitation when using database to manage templates, you can do yourself.<br />
<!-- HTML generated using hilite.me -->
<div  class="div-example">
<pre style="margin: 0; line-height: 125%">ExcelHandler handler = <span style="color: #0000ff">new</span> ExcelHandler();

<span style="color: #008000">//implements ITemplateService interface</span>
MyDatabaseTemplateService service = <span style="color: #0000ff">new</span> MyTemplateService();
handler.SetTemplateServiceservice(service);

<span style="color: #008000">//or</span>
MyDatabaseTemplateService service = handler.GetTemplateServiceservice&lt;MyDatabaseTemplateService &gt;();
</pre>
</div>
<p><strong>3.4.3. <a name="3.4.3">Get templates from web service</a></strong><br />
If your templates managed on server and you use IExcelHandler on client side, you can tell ExcelTDF getting templates by web service. In this case, your web service must implement methods defined in ITemplateService but <strong>don&#8217;t need to implement the interface</strong> of ITemplateService. This feature gives you capability of managing your templates by web service very simple. Following is some code.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">ExcelHandler handler = <span style="color: #0000ff;">new</span> ExcelHandler();
...
TemplateServiceSoapClient templateService = handler.GetTemplateService&lt;TemplateServiceSoapClient&gt;();</pre>
</div>
<p><br/><br />
<strong>3.5. <a name="3.5">Template File</a></strong><br />
<strong>keywords</strong>:<br />
       <strong> . General variable</strong><br />
       <em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;${VAR1}</em><br />
       <strong> . Formula variable</strong><br />
       <em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#{=SUM(A20*SUM(VAR1)+VAR2)}</em><br />
       <strong> . Custom service variable</strong><br />
       <em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%{=XSPAGEBEAK}</em><br />
       <strong> . Parameter variable</strong><br />
       <em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;?{VAR=PARAM1}</em><br />
       <strong> . Template Range binding</strong><br />
       <em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ ExcelRange("MyRange", "A1", "Z20", "RowRangeService")]</em><br />
       <strong> . Excel Variable binding </strong><br />
       <em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Excel("VAR1"......)]</em></p>
<p><strong>3.5.1. <a name="3.5.1">Variables in Template</a></strong><br />
When template processing, IExcel2007TemplateParser will search variables in the template and collect mapped information of variable and cell name. As the result, variables are mapped into data value after Excel2007DataParser parsed document. Template variable is a name of an arbitrary text string, whose formats are defined as ${..}, #{..}, %{..}, ?{..} four types.</p>
<p><strong>3.5.1.1. <a name="3.5.1.1">General variable: ${VAR1}</a></strong><br />
VAR1 is a general variable.  ExcelTDF will replace the the variable with the value in data model or SQL query data or some others depending on what data provider is used. For the data model, here is an example.</p>
<p><a href="/wp-content/uploads/var1.png"><img src="/wp-content/uploads/var1.png" alt="" title="var1" width="203" height="65" class="aligncenter size-full wp-image-1139" /></a></p>
<div  class="div-example">
<pre style="margin: 0; line-height: 125%">[ExcelRange(&quot;ROOT&quot;, &quot;A1, &quot;C3&quot;, &quot;RowRangeService&quot;)]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">MyTestMode</span>

    [Excel(&quot;VAR1&quot;)]
    <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> MyName {<span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }
}
</pre>
</div>
<p>As the above, after processed, the variable of ${VAR1} will be replaced by value of MyName property in the data mode of MyTestMode. If ${VAR1} is in list range and MyTestMode is element of list, The ${VAR1} will be the value of each element MyTestMode in the list.</p>
<p><strong>3.5.1.2. <a name="3.5.1.2">Formula variable: #{VAR2=SUM(VAR1, CJ12, 20)}</a></strong><br />
Formula variable is an Excel formula expression variable. After processed, the cell of formula variable will be a normal Excel formula function expression, such as =SUM(R12) etc. In the above expression, the left side of the equal &#8220;=&#8221; is variable name VAR2, and the right side is expression. Here VAR2&#8242;s value is the sum of VAR1. ExcelTDF will search VAR1 variable and compute the cell name of VAR1 automatically. In the expression of formula variable, you can use both normal cell name, such as  CJ12, AR12:AR20, $AR$20 and variable name. ExcelTDF is able to identify expression variable type of cell name, variable, text and number. For example, assume that VAR1 is in the list range and the cells are AK20,AK21,AK22 after range is processed, the variable of #{VAR2=SUM(VAR1, CJ12, 20)} will be explained as the sum of =SUM(AK20,AK21,AK22, CJ12, 20).<br />
<a href="/wp-content/uploads/var2.png"><img src="/wp-content/uploads/var2.png" alt="" title="var2" width="319" height="64" class="aligncenter size-full wp-image-1142" /></a></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">#{VAR2=SUM(VAR1, CJ12, 20)} --&gt; =SUM(AK20,AK21,AK22, CJ12, 20)</pre>
</div>
<div  class="div-example">
<pre style="margin: 0; line-height: 125%">[ExcelRange(&quot;ROOT&quot;, &quot;A1, &quot;C3&quot;, &quot;RowRangeService&quot;)]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">MyTestMode</span>

    [Excel(&quot;VAR1&quot;)]
    <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> MyName {<span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }

    [Excel(&quot;VAR2&quot;)]
    <span style="color: #0000ff">public</span> <span style="color: #2b91af">double</span> Sum {<span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }
}
</pre>
</div>
<p>Formula variable expression is able to has sub expression. Generally no limitation on the formula expression, you can use as normal excel file. Here is complicated one. The variable&#8217;s name is MYNO, in the expression, no other variables referenced.</p>
<div style="overflow: auto; width: auto; color: black; background: none repeat scroll 0% 0% white; padding: 0.2em 0.6em;">
<pre style="margin: 0; line-height: 125%;">#{MYNO=IF(ISERROR(MATCH("◎", R6:BZ6, 0))=FALSE,
    HLOOKUP("◎", R6:BZ9, 3, FALSE),
    IF(ISERROR(MATCH("○", R6:BZ6, 0))=FALSE,
          HLOOKUP("○", R6:BZ9, 3, FALSE),
          IF(ISERROR(MATCH("▲", R6:BZ6, 0))=FALSE,
                 HLOOKUP("▲", R6:BZ9, 3, FALSE),
                 IF(ISERROR(MATCH("△", R6:BZ6, 0))=FALSE,
                       HLOOKUP("△", R6:BZ9, 3, FALSE),
                       ""
                       )
                )
          )
    )}</pre>
</div>
<p>The following are also formula variables. In the expression, TRACKNO, FACTOR, QUANTITY, PRICE, BASEPRICE are referenced variables, ExcelTDF will replace them with correct cell names when building formula.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">#{VAR2=CONCATENATE("ABCD",LEFT(TRACKNO,1))}
#{VAR2=SUM(FACTOR*SUM(QUANTITY*PRICE))+ BASEPRICE*15%}</pre>
</div>
<p><strong>If no other variable references VAR2, the name of VAR2 can be omitted.</strong> for example</p>
<div style="overflow: auto; width: auto; color: black; background: none repeat scroll 0% 0% white; padding: 0.2em 0.6em;">
<pre style="margin: 0; line-height: 125%;">#{=SUM(FACTOR*SUM(QUANTITY*PRICE))+ BASEPRICE*15%}</pre>
</div>
<p>Certainly, you can use excel formula directly if the cell name is not changed dynamically and don&#8217;t need to reference a variable. ExcelTDF don&#8217;t process them, for example =SUM(12*C12), <strong>this is not a variable</strong>.</p>
<p>In the excel formula variable expression, you can use custom <strong>custom function service</strong> as the same as Excel function. About <strong>custom function service</strong>, please see next section of Custom service variable.</p>
<p><strong>3.5.1.3. <a name="3.5.1.3">Custom service variable: %{VAR3=XFSRANGE(RACENO)}</a></strong><br />
Custom service variable is customized cell service or function service, which is scalable functionality  provided by ExcelTDF. ExcelTDF provides several custom cell services and function services.<br />
You can develop your custom cell service and function service too. Custom services are used to processing special cells or some computing functionality. There are two types of custom services, one is Cell Service which implements interface of IExcelCellService, and another is Function Service which implements interface of IExcelFunctionService. IExcelFunctionService is a sub interface of IExcelCellService. The two types of services are used for different purpose. In order to distinguish from Excel formula functions, cell service name and function service name in ExcelTDF start with XS and XF. In fact the name is the object id defined in the Spring.NET configuration file.</p>
<div  class="div-example">
<pre style="margin: 0; line-height: 125%">&lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;XFSRANGE&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.Service.XFSiblingRangeFunctionService, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;
</pre>
</div>
<p><br/><br />
<a href="/wp-content/uploads/var3.png"><img src="/wp-content/uploads/var3.png" alt="" title="var3" width="319" height="61" class="aligncenter size-full wp-image-1146" /></a></p>
<div  class="div-example">
<pre style="margin: 0; line-height: 125%">[ExcelRange(&quot;ROOT&quot;, &quot;A1, &quot;C3&quot;, &quot;RowRangeService&quot;)]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">MyTestMode</span>

    [Excel(&quot;VAR1&quot;)]
    <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> MyName {<span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }

    [Excel(&quot;VAR2&quot;)]
    <span style="color: #0000ff">public</span> <span style="color: #2b91af">double</span> Sum {<span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }

    [Excel(&quot;VAR3&quot;)]
    <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> No {<span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }

}
</pre>
</div>
<p><br/><br />
If no other variable references VAR3, the name of VAR3 can be omitted. for example<br />
<!-- HTML generated using hilite.me -->
<div  class="div-example">
<pre style="margin: 0; line-height: 125%">%{=XFSRANGE(VAR1)}
</pre>
</div>
<p><br/><br />
<strong>3.5.1.3.1. <a name="3.5.1.3.1">Cell Service</a></strong><br />
Cell service does some special processing, for example, showing a barcode.  Cell service has no result returned. Following are some cell services provided by ExcelTDF.</p>
<p>	XSBARCODE:  output a barcode<br />
	XSCHECKBOX: output a checkbox<br />
	XSPAGEBREAK: add page break of excel<br />
	XSVDLIST:   showing cell as pulldown list</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">%{=XSBARCODE("BCODE", BARCODE_NO, "UPC-A")}
%{=XSCHECKBOX(1, PLAYER)}
%{=XSPAGEBREAK(20)}
%{AAA=XSVDLIST(RESULT)}</pre>
</div>
<p>On the above, in the expression, BARCODE_NO, PLAYER, RESULT is referenced template variables.</p>
<p><strong>3.5.1.3.2. <a name="3.5.1.3.2">Function Service</a></strong><br />
Function Service does some processing and returns the result as string. Depending on what you want to do, the function&#8217;s result maybe is variable&#8217;s cell name or variable&#8217;s value. The function is able to have sub expression in which another custom function might be called. The following is a example.<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">%{=XFOFFSET(XFMATCH("◎,○,▲", RACENO, 1), 0, 1)}</pre>
</div>
<p>In the above, custom function XFMATCH is called, and the result of XFMATCH  becomes a parameter of custom function XFOFFSET.</p>
<p>Because custom function returns the result, the custom function can be called in expression of Excel formula variable expression, such as the below.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">#{=CONCATENATE(XFOFFSET(XFMATCH("◎,○,▲", RACENO, 1), 0, 1), "=", XFOFFSET(XFMATCH("○,▲,△", RACENO, 1), 0, 1), XFOFFSET(XFMATCH("△", RACENO, 1), 0, 1))}</pre>
</div>
<p>In the above, in excel formula function expression CONCATENATE, custom function XFOFFSET and XFMATCH are called.</p>
<p><em><strong>Note</strong>: Custom function service can not call excel function as sub expression because the custom function service and cell service are processed only one time while workbook are loading, not in the period of running.</em></p>
<p><strong>3.5.1.4. <a name="3.5.1.4">Parameter variable:  ?{VAR2}</a></strong><br />
Parameter variable is used to specify parameter when searching the data. This is run-time functionality like CrystalReport, in the version 1.0.0.0, no support for parameter variable.</p>
<p><strong>3.5.1.5. <a name="3.5.1.5">Data type of variable</a></strong><br />
In ExcelTDF, you can specify data type forcibly. You just need to add a special char after the leading of letter. N is number type, C is currency type, D is date type. If no N, C, D specified, the variable considered as general string type. In the version of 1.0.0.0, type N, C will forcibly set cell type as NUMBER, D is now processed as string type.  Don&#8217;t confuse the data type with data output format. Output format such as $#,###,### is set by excel on the template designing, data type just tell excel the output data is whether a number or not etc. The following is examples.</p>
<p>General variable ${VAR1}, $N{VAR1}, $C{VAR1}, $D{VAR1}<br />
${VAR1}:   output as type of string or standard<br />
$N{VAR1}: output should be a number and ExcelTDF set the cell&#8217;s type to Number<br />
$C{VAR1}: output should be currency and ExcelTDF set the cell&#8217;s type to Number<br />
$D{VAR1}: output should be date and ExcelTDF does as string or standard in the version 1.0.0.0</p>
<p>The same rules are used for formula variables, custom service variables and parameter variables.<br />
Formula variable:  #{..}, #N{..}, #C{..}, #D{..}<br />
Custom service variable:  %{..}, %N{..}, %C{..}, %D{..}<br />
Parameter variable: ?{..}, ?N{..}, ?C{..}, ?D{..}</p>
<p><strong>3.5.1.6. <a name="3.5.1.6">The Range of variable</a></strong><br />
In a range, variable must be unique, but in different range, there is no this limitation. When a variable is referenced by formula or custom service, ExcelTDF try to search the variable and find cell names or values of variable. ExcelTDF search variable by some orders. ExcelTDF always search expression variable first from the range of variable itself. If not found, ExcelTDF then search expression variable from child ranges. Last, try to search expression variable from all. Understanding the searching order will help you to get correct result.</p>
<p><strong>3.5.2. <a name="3.5.2">Template range</a></strong><br />
Template range is an excel range specified by row index or column index or excel cell name. <strong>Range Service Name</strong> must be specified to identify which template range to be processed by ExcelTDF. Template range is defined both by object in Spring.NET configuration file and by Metadata defined in data model. Defined items in template range are the properties of type of class <strong>TemplateRange</strong>.</p>
<p>When you design your template, the first thing is that you should determine how to output data with template. You can determine how many template ranges there are and how to process template ranges according to your data structure. If your data is a list, define a template range as a list service range will simplify your processing. Please see the examples to understand Template Range and Range Services.</p>
<p>Template file is a Excel workbook(*.xlsx). In this version only *.xlsx format is supported. As the known, one workbook might have several worksheets. ExcelTDF splits a worksheet as some ranges which include  some cells to be processed or not. For the cells to be processed,  the cell text might include one or more defined variables. A range might have some child ranges, and child range is able to has its own child ranges too. These range&#8217;s definition information must be specified by template range configuration file or defined by Metadata in data model. So the whole worksheet is considered as a root range, all other ranges are worksheet&#8217;s child or descendant ranges.</p>
<p>See the following diagram. The worksheet root range has three child ranges named R-A, R-E, R-D, and range R-A also has two child range R-B, R-C. From diagram we can see a tree of range.<br />
<a href="/wp-content/uploads/2010/09/template-range.png"><img class="aligncenter size-full wp-image-227" title="template-range" src="/wp-content/uploads/2010/09/template-range.png" alt="" width="824" height="456" /></a></p>
<p>The template range configuration file, simply, we can consider it as TemplateRange class. The all items&#8217; name are TemplateRange&#8217;s properties. The service name used to process range is listed in <a href="#servicenames">service names</a>, You can get all names by call OpenXmlContext&#8217;s GetRangeServiceIds() methods too.</p>
<p>The following is template whose layout is the same as description above.<br />
<a href="/wp-content/uploads/range.png"><img src="/wp-content/uploads/range.png" alt="" title="range" width="420" height="490" class="aligncenter size-full wp-image-1157" /></a></p>
<p>The following is corresponding  template range configuration file.</p>
<div  class="div-example">
<pre style="margin: 0; line-height: 125%">&lt;?xml version=<span style="color: #a31515">&quot;1.0&quot;</span> encoding=<span style="color: #a31515">&quot;utf-8&quot;</span>?&gt;
&lt;objects xmlns=<span style="color: #a31515">&quot;http://www.springframework.net&quot;</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;SAMPLE_SHEET1&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;RootRange&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;A1&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;Z51&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;RowRangeService&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ChildRanges&quot;</span>&gt;
      &lt;list element-type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span>&gt;
        &lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;R-A-ID&quot;</span> /&gt;
	&lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;R-E-ID&quot;</span> /&gt;
	&lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;R-D-ID&quot;</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;R-A-ID&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;R-A&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;B3&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;S31&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BlockRangeService&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ChildRanges&quot;</span>&gt;
      &lt;list element-type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span>&gt;
        &lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;R-B-ID&quot;</span> /&gt;
        &lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;R-C-ID&quot;</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;R-E-ID&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;R-E&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;B37&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;S49&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span>  <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BlockRangeService&quot;</span>/&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;
 
  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;R-D-ID&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;R-D&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;U2&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;Y49&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span>  <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BlockRangeService&quot;</span>/&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;R-B-ID&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;R-B&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;C9&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;Q16&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span>  <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BlockRangeService&quot;</span>/&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;R-C-ID&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;R-C&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;B20&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;Q29&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span>  <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BlockRangeService&quot;</span>/&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

&lt;/objects&gt;
</pre>
</div>
<p><br/><br />
The following is model class used to process template above.<br />
<!-- HTML generated using hilite.me -->
<div  class="div-example">
<pre style="margin: 0; line-height: 125%">[ExcelRange(&quot;SHEET1&quot;)]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RT</span>
{
	[ExcelRange(&quot;R-A&quot;)]
	<span style="color: #0000ff">public</span> RA ra;
	
	[ExcelRange(&quot;R-D&quot;)]
	<span style="color: #0000ff">public</span> RD rd;

	[ExcelRange(&quot;R-E&quot;)]
	<span style="color: #0000ff">public</span> RE re;
}


<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RA</span>{

	[ExcelRange(&quot;R-B&quot;)]	
	<span style="color: #0000ff">public</span> RB rb;

	[ExcelRange(&quot;R-C&quot;)]
	<span style="color: #0000ff">public</span> RC rc
}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RB</span> {}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RC</span> {}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RD</span> {}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RE</span> {}
	
</pre>
</div>
<p><br/><br />
If you want to define range&#8217;s all information into Metadata to replace template range configuration file, the following is sample of data model.<br />
<!-- HTML generated using hilite.me -->
<div  class="div-example">
<pre style="margin: 0; line-height: 125%">[ExcelRange(&quot;SHEET1&quot;, &quot;A1&quot;, &quot;Z51&quot;, &quot;RowRangeService&quot;)]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RT</span>
{
	[ExcelRange(&quot;R-A&quot;, &quot;B3&quot;, &quot;S31&quot;, &quot;BlockRangeService&quot;)]
	<span style="color: #0000ff">public</span> RA ra;
	
	[ExcelRange(&quot;R-D&quot;, &quot;U2&quot;, &quot;Y49&quot;, &quot;BlockRangeService&quot;)]
	<span style="color: #0000ff">public</span> RD rd;

	[ExcelRange(&quot;R-E&quot;, &quot;B37&quot;, &quot;Y49&quot;, &quot;BlockRangeService&quot;)]
	<span style="color: #0000ff">public</span> RE re;
}


<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RA</span>{

	[ExcelRange(&quot;R-B&quot;, &quot;C9&quot;, &quot;Q16&quot;, BlockRangeService&quot;)]	
	<span style="color: #0000ff">public</span> RB rb;

	[ExcelRange(&quot;R-C&quot;, &quot;B20&quot;, &quot;Q29&quot;, &quot;BlockRangeService&quot;)]
	<span style="color: #0000ff">public</span> RC rc
}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RB</span> {}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RC</span> {}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RD</span> {}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RE</span> {}
	
</pre>
</div>
<p><br/><br />
<strong>3.5.2.1. <a name="3.5.2.1">Template range example 1</a></strong><br />
Next let us see how to determine your template range by some examples.<br />
First, see the following most simple example. We just want  to replace the variables between row 8 and row 10, so the worksheet has only one root range from row 8 to row 10.</p>
<p><a href="/wp-content/uploads/template-example11.png"><img src="/wp-content/uploads/template-example11.png" alt="" title="template-example1" width="1247" height="327" class="aligncenter size-full wp-image-1164" /></a></p>
<p>In order to tell ExcelTDF the range&#8217;s information , we write these information into a Spring.NET object xml file as following.<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span>
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span> &gt;
    <span style="color: #008000;">&lt;!-- sheet 1 --&gt;</span>
      &lt;object id=<span style="color: #a31515;">"RowRangeServiceTest_sheet1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
        &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ROOT"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"Top"</span> value=<span style="color: #a31515;">"8"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"Bottom"</span> value=<span style="color: #a31515;">"10"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span>/&gt;
      &lt;/object&gt;
&lt;/objects&gt;</pre>
</div>
<p>On the above, in configuration file, the type of object is always JanaBiz.OpenXml.TemplateRange. TemplateRange has some properties must be specified. These properties are RangeName, ServiceId and range defined by (Top|Left|LeftTop) and (Bottom|Right|RightBottom). If we want to specify range by row index without column limitation, the Top and Bottom property should be set. If we want to specify range by column index without limitation of row index, the Left and Right property should be set. If we want to specify rectangle range with the limitation of row and column, the property LeftTop and RightBottom should be set.</p>
<p>	RangeName: the identifier of the range<br />
	Top/Bottom | Left/Right | LeftTop/RightBottom :  the range specified by row or column or cell name<br />
	ServiceId:  the service name used to process this range. <a href="#servicenames">see service names</a></p>
<p>The object id can be any string but it must be unique in all configuration files, For the worksheet root range, it is best to assign object id as <strong>template id + &#8220;sheet&#8221; + worksheet index </strong>. This will be convenient to ExcelTDF to find worksheet root range object. About some other property please see TemplateRange class API.</p>
<p>For the template above, following is the processed result. Because the service is RowRangeService, it just replaces the variables in specified template range with the data in data model.</p>
<p><a href="/wp-content/uploads/template-example1-result.png"><img src="/wp-content/uploads/template-example1-result.png" alt="ExcelTDF " title="template-example1-result" width="1249" height="323" class="aligncenter size-full wp-image-1166" /></a></p>
<p><strong>3.5.2.2. <a name="3.5.2.2">Template range example 2</a></strong><br />
Following is another template file. In this template file we want to output data as a list. The list&#8217;s element is from row 8 to row 10, let us see how different result will be got.</p>
<p>The template file is shown as following.</p>
<p><a href="/wp-content/uploads/template-example2.png"><img src="/wp-content/uploads/template-example2.png" alt="" title="template-example2" width="1248" height="528" class="aligncenter size-full wp-image-1168" /></a></p>
<p>The template configuration file is shown as following.</p>
<p><!-- HTML generated using hilite.me -->
<div class="div-example">
<pre style="margin: 0; line-height: 125%">&lt;?xml version=<span style="color: #a31515">&quot;1.0&quot;</span> encoding=<span style="color: #a31515">&quot;shift_jis&quot;</span>?&gt;
&lt;objects xmlns=<span style="color: #a31515">&quot;http://www.springframework.net&quot;</span> &gt;
  &lt;!-- sheet 1 --&gt;
  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;RowListRangeServiceTest_SHEET1&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;ROOT&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;Top&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;1&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;Bottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;30&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;RowRangeService&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ChildRanges&quot;</span>&gt;
      &lt;list element-type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span>&gt;
        &lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;RLRSChildList1&quot;</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;RLRSChildList1&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;CHILDLIST1&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;L8&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BN10&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;RowListRangeService&quot;</span>/&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

&lt;/objects&gt;
</pre>
</div>
<p>There are two TemplateRanges in worksheet. The worksheet root range, whose RangeName is ROOT and it has a  child range. Root range is from row 8 to row 22. Child range&#8217;s id is <strong>RLRSChildList1 </strong>and RangeName is CHILDLIST1. Child range is from L8 to BE10. Child range is processed by service of <strong>RowListRangeService </strong>which output data as list with the same format as defined range L8:BE10, Assume your list in the data model has 5 elements, the data of 5 elements will be outputted from L8 to L20.</p>
<p>The following is processed result.</p>
<p><a href="/wp-content/uploads/template-example2-result.png"><img src="/wp-content/uploads/template-example2-result.png" alt="" title="template-example2-result" width="1247" height="527" class="aligncenter size-full wp-image-1170" /></a></p>
<p>If we change the ROOT range&#8217;s row from row 7 to row 20, what will be changed? The variable of ${HouseNumber1} is in the range of ROOT, this variable will be processed. ROOT range&#8217;s ServiceId is RowRangeService, the variable is just replaced by value in data model corresponding to the ROOT range.</p>
<p><strong>3.5.2.3. <a name="3.5.2.3">Template range example 3</a></strong><br />
Next, let us see a some complicated examples. In this example we want to output a list, and the element of list is also a list. We usually bump into this case. As the shown, template design is very simple too. The outer list&#8217;s element is from B5 to BJ11, the inner list&#8217;s element is from C8 to BE10. So the variable of $N{HouseNumber1}, #C{S1=SUM(HBⅡBody)}, #C{=SUM(S10)} etc. are processed by outer list. Inner list size might be different, the service of specified will process them correctly.</p>
<p><a href="/wp-content/uploads/template-example3.png"><img src="/wp-content/uploads/template-example3.png" alt="" title="template-example3" width="1143" height="347" class="aligncenter size-full wp-image-1172" /></a></p>
<p>As the diagram of following, the worksheet has three ranges. Root range of worksheet is from row 1 to 18, which is processed by RowRangeService. The root range has a child range whose id is CRCRS_PARENTLIST1, named PARENTLIST1 and colored with gray. Child range is from B5 to BJ11, which is processed by service of <strong>ComplexRowCloneRangeService</strong>. The service named with prefix of  ComplexXX is used to process list ranges who&#8217;s element has child range. So the part of B5:BJ11 will be cloned list size-1 times. The cloned rows are inserted in the below of the last row BJ<strong>11</strong>, here it is row 12. Because the element of list includes a child range,  whose id is CRCRS_CHILDLIST1 , this range is also a cloned list, the cloned rows is from C8 to BE10, The row of parent range will be changed dynamically. ExcelTDF control ranges processing order, first parent range, then child ranges. If child range is a coned list, parent range&#8217;s row or column will be changed automatically.</p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%">&lt;?xml version=<span style="color: #a31515">&quot;1.0&quot;</span> encoding=<span style="color: #a31515">&quot;utf-8&quot;</span>?&gt;
&lt;objects xmlns=<span style="color: #a31515">&quot;http://www.springframework.net&quot;</span> &gt;
  &lt;!-- sheet 1 --&gt;
  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;ComplexRowCloneRangeServiceTest_SHEET1&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;ROOT&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;Top&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;1&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;Bottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;18&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;RowRangeService&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ChildRanges&quot;</span>&gt;
      &lt;list element-type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span>&gt;
        &lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;CRCRS_PARENTLIST1&quot;</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;CRCRS_PARENTLIST1&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;PARENTLIST1&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;B5&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BJ11&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;ComplexRowCloneRangeService&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ChildRanges&quot;</span>&gt;
      &lt;list element-type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span>&gt;
        &lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;CRCRS_CHILDLIST1&quot;</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;CRCRS_CHILDLIST1&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;CHILDLIST1&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;C8&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BE10&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;RowCloneRangeService&quot;</span>/&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

&lt;/objects&gt;
</pre>
</div>
<p>The result is shown in the following. You can see, the simple template creates complicated data output. There are many patterns you can assemble by provided services in ExcelTDF.</p>
<p><a href="/wp-content/uploads/template-example3-result.png"><img src="/wp-content/uploads/template-example3-result.png" alt="" title="template-example3-result" width="1075" height="697" class="aligncenter size-full wp-image-1173" /></a></p>
<p><strong>3.5.3. <a name="3.5.3">Without template range file</a></strong><br />
If your template doesn’t need to be changed frequently, maybe you don&#8217;t want to create template range configuration file. In this case the template range information can be written in code as metadata of program. If you write range information into code, and your template layout is changed, you must modify your code. The most benefit of using template range configuration file is you don&#8217;t have to change your code if template layout changed.  For the detail, please see next chapter about data provider.</p>
<p><strong>3.6. <a name="3.6">Data Provider and Data Model</a> </strong><br />
ExcelTDF uses two types of interface to control the mapping information. IDataProviderManager controls mapping behavour of IRangeDataProvider and template range, while IRangeDataProvider controls mapping behavour of data field in data model and template variable. Data field maybe is field or property  in data model, or columns of SQL query, or some others.</p>
<p><strong>3.6.1 <a name="3.6.1">The types of data provider manager</a></strong><br />
Each implementation class of IDataProviderManager knows how to map data provider to template range. Actually manager maps RangeData in IRangeDataProvider to template range. RangeData can be data model, DataSet or other data objects. ExcelTDF provides three manager classes.</p>
<p><strong>3.6.1.1. <a name="3.6.1.1">DataModelProviderManager</a></strong><br />
DataModelProviderManager, in which the default DataModelRangeDataProvider is used,  maps data model to template range. ExcelRange and ExcelAttibute(Excel) Attribute classes are used to help ExcelTDF doing those works. The RangeData in DataModelRangeDataProvider is your data model for DataModelProviderManager. In the next you will see how to use them in data model.</p>
<p><strong>3.6.1.2. <a name="3.6.1.2">QueryProviderManager</a></strong><br />
QueryProviderManager let you create document or report by specified SQL query, all template ranges use the same one query data if you use QueryProviderManager. If you are familiar with CrystalReport, creating a query and getting report, this is the similarity functionality.</p>
<p><strong>3.6.1.3. <a name="3.6.1.3">AnyTypeProviderManager</a></strong><br />
AnyTypeProviderManager let you create document or report by any data type. You should create IRangeDataProvider for each template range. If no IRangeDataProvider found, the IRangeDataProvider of parent range will be used. You can specify a data model for a range, SQL query for another range. You can specify SQL query for each range and so on.  It is the most flexible manager.</p>
<p>See the following diagram, it shows the association between template and data.</p>
<p><a href="/wp-content/uploads/2010/09/dataprovider3.png"><img class="aligncenter size-full wp-image-300" title="dataprovider" src="/wp-content/uploads/2010/09/dataprovider3.png" alt="" width="905" height="534" /></a></p>
<p>As you see, ExcelTDF provides various IRangeDataProvider implementation classes, from data mode to usually used database, even SAP. IRangeDataProvider has two methods ReadRangeData() for getting data from database or background service, and WriteRangeData() for saving edited data to database or sending to background service. ExcelTDF maps RangeData in IRangeDataProvider to template range. ExcelTDF provides three IDataProviderManager implementation classes, they are DataModelProviderManager,  QueryProviderManager and  AnyTypeProviderManager. The three data provider managers have the different control behavior and are used in different way. The DataModelProviderManager is the most often used data provider manager. If the RangeData in IRangeDataProvider is data model, not a SQL DataSet and not SAP&#8217;s DataReader, DataModelProviderManager is your suitable selection.</p>
<p><strong>3.6.2 <a name="3.6.2">Data model of Template range example 1</a></strong><br />
In the following, let us see how to use DataModelProviderManager and what your data model should be.<br />
For the Template range example-1 which we discussed on the above, data model is shown in the diagram. Please see the fields that have defined Excel metadata, for example  [Excel("HBⅡBody")], it will map the value of HBⅡBody to the template variable defined as ${HBⅡBody}. Every template variable must have corresponding metadata with the same name in data model. If [Excel("X")] is defined in data model, but no ${X} or #{X=..} or %{X=..} found, &#8220;X&#8221; can be used in formula expression and custom service expression. For example, #{VAR2=SUM(VAR1*X/100)}, X is not a variable in template but a variable in data model. In the same way, the metadata [ExcelRange("ROOT")] tells ExcelTDF that the range information named ROOT in the template range configuration is used for this model, and variables defined in this model by metadata are mapped to template variables in the range named ROOT.</p>
<p><!-- HTML generated using hilite.me -->
<div class="div-example">
<pre style="margin: 0; line-height: 125%"><span style="color: #0000ff">using</span> System;
<span style="color: #0000ff">using</span> System.Xml.Serialization;
<span style="color: #0000ff">using</span> JanaBiz.OpenXml;

<span style="color: #0000ff">namespace</span> OpenXmlDemoData.Data
{

    [ExcelRange(&quot;ROOT&quot;)]
    [Serializable]
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RowRangeServiceData1</span>
    {
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> HouseType;

        [Excel(&quot;HouseNumber1&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> HouseNum = <span style="color: #a31515">&quot;20&quot;</span>;

        [Excel(&quot;HBⅡBody&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">double</span> HBⅡBody;

        [Excel(&quot;VAR2&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> Var2;

        [Excel(&quot;LBⅡBody&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> LBⅡBody;

        [Excel(&quot;KCBody&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> KCBody;

        [Excel(&quot;SHⅡBody&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> SHⅢBody;

        .....
    }
}
</pre>
</div>
<p>Here is the code to parse template and get your document. As you see, after you finished your template design and wrote well your template configuration, the coding is very simple.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;

<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Handler;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Config;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Data;
<span style="color: #0000ff;">using</span> OpenXmlDemoData;

<span style="color: #0000ff;">namespace</span> TemplateConvertDemo
{
    <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">Program</span>
    {
        <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> Main(<span style="color: #2b91af;">string</span>[] args)
        {
            <span style="color: #008000;">//create your handler </span>
            IOpenXmlHandler handler = <span style="color: #0000ff;">new</span> OpenXmlHandler();

            <span style="color: #008000;">//tell ExcelTDF which ITemplateService is used to </span>
            <span style="color: #008000;">//get template file and template range configuration</span>
            handler.GetTemplateService&lt;LocalTemplateService&gt;();

            <span style="color: #008000;">//tell ExcelTDF which IDataProviderManager and </span>
            <span style="color: #008000;">//what data model is used to data              </span>
            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                <span style="color: #0000ff;">new</span> OpenXmlDemoData.Data.RowRangeServiceData1());

            <span style="color: #008000;">//set template id to identify which template is used</span>
            handler.TemplateId = <span style="color: #a31515;">"RowRangeServiceTest"</span>;

            <span style="color: #008000;">//parse your template </span>
            handler.ParseTemplate();

            <span style="color: #008000;">//parse your data </span>
            handler.ParseWorkbook(<span style="color: #0000ff;">null</span>);

            <span style="color: #008000;">//get parsed document</span>
            <span style="color: #2b91af;">byte</span>[] doc = handler.GetParsedDocument();

            <span style="color: #008000;">//release some resource</span>
            handler.Close();
        }
    }
}</pre>
</div>
<p>In the code, creating DataModelProviderManager with parameter of RowRangeServiceData1 will enable manager use default data provider of DataModelRangeDataProvider. In fact, DataModelProviderManager have two constructors with parameter of either data model or IRangeDataProvider when you want use your customized IRangeDataProvider.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">        <span style="color: #0000ff;">public</span> DataModelProviderManager(Object dataModel)

      <span style="color: #0000ff;">public</span> DataModelProviderManager(IRangeDataProvider rootRangeDataProvider)</pre>
</div>
<p>If you want to open parsed workbook into excel in your excel AddIn program directly, ExcelHandler is prepared for you.<br />
The code is shown as the following. The step of coding is the same as the above example. Here we create and initialize handler first, and get template file and template range configuration by web service of TemplateServiceSoapClient. <strong>So your web service should perform the methods of interface ITemplateService, but your service don&#8217;t have to implement the interface of ITemplateService</strong>. This will be helpful for you to reference web service directly.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">        <span style="color: #0000ff;">private</span> ExcelHandler handler = <span style="color: #0000ff;">null</span>;
        <span style="color: #0000ff;">private</span> TemplateServiceSoapClient webService = <span style="color: #0000ff;">null</span>;

        <span style="color: #0000ff;">public</span> RibbonDemo()
        {
            InitializeComponent();
        }

        <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> RibbonDemo_Load(<span style="color: #2b91af;">object</span> sender, RibbonUIEventArgs e)
        {
            InitializeExcelHandler();
        }

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Create and initialize &lt;see cref="IExcelHandler"/&gt;</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> InitializeExcelHandler()
        {
            <span style="color: #008000;">//create IExcelHandler instance</span>
            handler = <span style="color: #0000ff;">new</span> ExcelHandler();

            <span style="color: #008000;">// set excel application </span>
            handler.ExcelApp = Globals.ThisAddIn.Application;

            <span style="color: #008000;">//create or get template service </span>
            webService = handler.GetTemplateService&lt;TemplateServiceSoapClient&gt;();

            <span style="color: #008000;">//create data service </span>
            DataService dataService = <span style="color: #0000ff;">new</span> DataService();

            <span style="color: #008000;">//get excel data event handler</span>
            handler.OnGetDocumentData += dataService.GetDocumentData;

            <span style="color: #008000;">//save excel data event handler</span>
            handler.OnSaveDocumentData += dataService.SaveDocumentData;
        }</pre>
</div>
<p>On the above, we create DataService object which performs OnGetDocumentData event handler for getting data model. Certainly you can assign DataModelProviderManager to handler directly too,  such as<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                <span style="color: #0000ff;">new</span> OpenXmlDemoData.Data.RowRangeServiceData1());</pre>
</div>
<p>Define a event handler is very flexible. First, coding logic to get data for all templates can be put in event handler method. Second, you can override IRangeDataProvider, and get data in your way. The event handler method is show in the below.<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Assign a data provider manager or data range provider to a template for specified template id</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;param name="handler"&gt;&lt;/param&gt;</span>
        <span style="color: #008000;">/// &lt;param name="sheetIndex"&gt;&lt;/param&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> GetDocumentData(IOpenXmlHandler handler, <span style="color: #2b91af;">int</span> sheetIndex)
        {
            <span style="color: #0000ff;">switch</span> (handler.TemplateId)
            {
                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"RowRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            <span style="color: #008000;">// you can get from web service etc., for simple, here just new a data model </span>
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                            <span style="color: #0000ff;">new</span> RowRangeServiceData1());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;
            }
        }</pre>
</div>
<p>Let us see the code about opening parsed document, only several lines. Open() method try to find data provider manager and data provider by event handler of OnGetDocumentData. If event handler exists, it will be called.<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Open parsed workbook of spreadsheet</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;param name="templateId"&gt;&lt;/param&gt;</span>
        <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> OpenDocument(<span style="color: #2b91af;">string</span> templateId)
        {
            <span style="color: #008000;">//close opened workbook before</span>
            handler.Close();

            <span style="color: #008000;">//template id used</span>
            handler.TemplateId = templateId;
            <span style="color: #008000;">//other input parameter for get excel data </span>
            handler.InputData = <span style="color: #0000ff;">null</span>;
            <span style="color: #008000;">//parse template</span>
            handler.ParseTemplate();
            <span style="color: #008000;">//parse workbook and open it in excel or other component</span>
            handler.Open();
        }</pre>
</div>
<p><strong>3.6.3 <a name="3.6.3">Data model of Template range example 2</a></strong><br />
In this example because the root template range has a child range, the data model is also created into two classes hierarchically. RowListRangeServiceData class has metadata [ExcelRange("ROOT")] and its field member ChildList1 has metadata [ExcelRange("CHILDLIST1")]. The names of ROOT and CHILDLIST1 matches the RangeName defined in template range configuration. In template range configuration, the ServiceId of CHILDLIST1 is RowListRangeService, so in the data model of RowListRangeServiceData, the member with metadata  [ExcelRange("CHILDLIST1")], ChildList1  must be a list.</p>
<p><em>ExcelRange binding a data model is associated to template range, and if your template range ServiceId is list related service, data member should be a list type of IList. That is all.</em></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;
<span style="color: #0000ff;">using</span> JanaBiz.Common.Serialize;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data
{
    [Serializable]
    <strong>[ExcelRange("ROOT")]</strong>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">RowListRangeServiceData</span>
    {
        <span style="color: #0000ff;">public</span> RowListRangeServiceData()
        {
            <span style="color: #008000;">//Create data for demo</span>
            <span style="color: #0000ff;">for</span> (<span style="color: #2b91af;">int</span> i = 0; i &lt; 5; i++)
            {
                ChildList1.Add(<span style="color: #0000ff;">new</span> RowRangeServiceData1());
            }
        }

       <strong>[ExcelRange("CHILDLIST1")]</strong>
        <span style="color: #0000ff;">public</span> IList&lt;RowRangeServiceData1&gt; ChildList1 = <span style="color: #0000ff;">new</span> List&lt;RowRangeServiceData1&gt;();

    }
}</pre>
</div>
<p>In OnGetDocumentData event handler we added a piece of coding for getting data model. other works are the same as example-1</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Assign a data provider manager or data range provider to a template for specified template id</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;param name="handler"&gt;&lt;/param&gt;</span>
        <span style="color: #008000;">/// &lt;param name="sheetIndex"&gt;&lt;/param&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> GetDocumentData(IOpenXmlHandler handler, <span style="color: #2b91af;">int</span> sheetIndex)
        {
            <span style="color: #0000ff;">switch</span> (handler.TemplateId)
            {
                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"RowRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            <span style="color: #008000;">// you can get from web service etc., for simple, here just new a data model </span>
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                            <span style="color: #0000ff;">new</span> RowRangeServiceData1());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;

<strong>                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"RowListRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> RowListRangeServiceData());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;
</strong>            }
        }</pre>
</div>
<p><strong>3.6.4 <a name="3.6.4">Data model of Template range example 3</a></strong><br />
In this example, the template range has a list, and list&#8217;s element is also a list. Let us see the data model how to construct.<br />
As you have seen, entry class ComplexRowCloneRangeServiceData has metadata ExcelRange(&#8220;ROOT&#8221;), its member MasterDoorList1  has  metadata  [ExcelRange("PARENTLIST1")], MasterDoorList1 is a list.  MasterDoorList1&#8242;s element is RoomTypeList1 which has a member MasterDoorChildList, and MasterDoorChildList has metadata [ExcelRange("CHILDLIST1")], it is also a list. In the OnGetDocumentData event handler we added code to get data provider manager. For the others no need to change.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;

<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data
{
    <strong>[ExcelRange("ROOT")]</strong>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">ComplexRowCloneRangeServiceData</span>
    {
        <span style="color: #0000ff;">public</span> ComplexRowCloneRangeServiceData()
        {
            CreateDataForDemo();
        }
        <strong>[ExcelRange("PARENTLIST1")]</strong>
        <span style="color: #0000ff;">public</span> IList&lt;RoomTypeList1&gt; MasterDoorList1 = <span style="color: #0000ff;">new</span> List&lt;RoomTypeList1&gt;();
    }
}</pre>
</div>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data
{
    <span style="color: #008000;">/// &lt;summary&gt;</span>
    <span style="color: #008000;">/// 戸当りマスタ登録・変更画面の概要説明です。</span>
    <span style="color: #008000;">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">RoomTypeList1</span>
    {
        <span style="color: #0000ff;">public</span> RoomTypeList1()
        {
            CreateDataForDemo();
        }

        <span style="color: #0000ff;">public</span> RoomTypeList1(<span style="color: #2b91af;">string</span> houseNumber)
        {
            CreateDataForDemo2(houseNumber);
        }

        [Excel("部屋数1")]
        <span style="color: #0000ff;">public</span> <span style="color: #2b91af;">string</span> HouseNumber=<span style="color: #a31515;">"12"</span>;

        <strong>[ExcelRange("CHILDLIST1")]</strong>
        <span style="color: #0000ff;">public</span> IList&lt;RowRangeServiceData1&gt; MasterDoorChildList = <span style="color: #0000ff;">new</span> List&lt;RowRangeServiceData1&gt;();
    }
}</pre>
</div>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;
<span style="color: #0000ff;">using</span> System.Configuration;
<span style="color: #0000ff;">using</span> System.IO;
<span style="color: #0000ff;">using</span> System.Reflection;

<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Handler;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Data;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Config;

<span style="color: #0000ff;">using</span> OpenXmlDemoData.DataProvider;
<span style="color: #0000ff;">using</span> OpenXmlDemoData.Data;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData
{
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">DataService</span>
    {

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Assign a data provider manager or data range provider to a template for specified template id</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;param name="handler"&gt;&lt;/param&gt;</span>
        <span style="color: #008000;">/// &lt;param name="sheetIndex"&gt;&lt;/param&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> GetDocumentData(IOpenXmlHandler handler, <span style="color: #2b91af;">int</span> sheetIndex)
        {
            <span style="color: #0000ff;">switch</span> (handler.TemplateId)
            {
                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"RowRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            <span style="color: #008000;">// you can get from web service etc., for simple, here just new a data model </span>
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                            <span style="color: #0000ff;">new</span> RowRangeServiceData1());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;

                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"RowListRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> RowListRangeServiceData());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;

                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"ComplexRowCloneRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> ComplexRowCloneRangeServiceData());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;
            }
        }</pre>
</div>
<p><strong>3.6.5. <a name="3.6.5">How to create your class of IRangeDataProvider </a></strong><br />
If you need to search data from database, web service or other services in background, you might want to create your own implementation class of IRangeDataProvider. If your searched result is designed as data model demonstrated in the example above, the most convenient way is to create a sub class of DataModelRangeDataProvider. DataModelRangeDataProvider performs interface methods of IRangeDataProvider, but ReadRangeData() and WriteRangeData() do nothing. You can override these two methods in your way. When you open or parse document, firstly, IDataProviderManager calls ReadRangeData() to get data, then IDataProviderManager parses gotten data. When you save edited document by calling ExcelHandler or OpenXmlHandler&#8217;s Save() method, firstly, the Save() method will call Flush() method to save edited data into mapped data model of RangeData then call WriteRangeData() to save RangeData to database or other services.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;
<span style="color: #0000ff;">using</span> System.IO;
<span style="color: #0000ff;">using</span> System.Reflection;

<span style="color: #0000ff;">using</span> JanaBiz.Common.Serialize;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Data;
<span style="color: #0000ff;">using</span> OpenXmlDemoData.Data.Boat;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.DataProvider
{
    <span style="color: #008000;">/// &lt;summary&gt;</span>
    <span style="color: #008000;">/// </span>
    <span style="color: #008000;">/// This is demo for getting data from database or background service.</span>
    <span style="color: #008000;">/// Here we get data from xml resource file.</span>
    <span style="color: #008000;">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">ColumnDataProvider</span> : DataModelRangeDataProvider
    {

        <span style="color: #0000ff;">public</span> ColumnDataProvider()
            : <span style="color: #0000ff;">base</span>()
        {
        }

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Here you can call database service, web service of other background service to </span>
        <span style="color: #008000;">/// read data, the last step is assign the result data to RangeData.</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">override</span> <span style="color: #0000ff;">void</span> ReadRangeData()
        {
            <span style="color: #008000;">//here, read from xml file</span>
            Assembly assembly = Assembly.GetExecutingAssembly();
            <span style="color: #2b91af;">string</span> assemblyNamespace = assembly.FullName.Split(<span style="color: #0000ff;">new</span> <span style="color: #2b91af;">char</span>[]{<span style="color: #a31515;">','</span>})[0];
            <span style="color: #2b91af;">string</span> xmlfile = assemblyNamespace + <span style="color: #a31515;">".Resources.ColumnRangeTestData.xml"</span>;
            Stream stream = assembly.GetManifestResourceStream(xmlfile);
            BoatRace boatRace = Serializer.ReadModel&lt;BoatRace&gt;(stream);

            <span style="color: #008000;">//this must be done </span>
            <span style="color: #0000ff;">this</span>.RangeData = boatRace;
        }

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// You can write your saving data in your way.</span>
        <span style="color: #008000;">/// Here we just write the data into a xml file </span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;returns&gt;return true, if saved data successfully, otherwise false&lt;/returns&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">override</span> <span style="color: #2b91af;">bool</span> WriteRangeData()
        {
            Serializer.WriteToXml(<span style="color: #0000ff;">this</span>.RangeData, <span style="color: #a31515;">"c:\\ColumnListRangeTestData.xml"</span>);
            <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span>;
        }

    }
}</pre>
</div>
<p>In the example on the above, for simply demo, ColumnDataProvider just get data from a serialized xml resource file and write edited data into xml resource file. Next code is show how to assign the data provider to IDataProviderManager.<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Assign a data provider manager or data range provider to a template for specified template id</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;param name="handler"&gt;&lt;/param&gt;</span>
        <span style="color: #008000;">/// &lt;param name="sheetIndex"&gt;&lt;/param&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> GetDocumentData(IOpenXmlHandler handler, <span style="color: #2b91af;">int</span> sheetIndex)
        {
            <span style="color: #0000ff;">switch</span> (handler.TemplateId)
            {
                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"RowRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            <span style="color: #008000;">// you can get from web service etc., for simple, here just new a data model </span>
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                            <span style="color: #0000ff;">new</span> RowRangeServiceData1());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;

<strong>                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"ColumnListRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> ColumnDataProvider());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;
                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"ColumnCloneRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> ColumnDataProvider());
                            <span style="color: #0000ff;">break</span>;
                        <span style="color: #0000ff;">case</span> 1:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> ColumnDataProvider());
                            <span style="color: #0000ff;">break</span>;

                    }
                    <span style="color: #0000ff;">break</span>;
                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"ComplexColumnCloneRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> ComplexColumnDataProvider());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;

                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"ComplexColumnListRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> ComplexColumnDataProvider());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;
</strong>            }
        }</pre>
</div>
<p><strong>3.6.6. <a name="3.6.6">Use Metadata without template range configuration</a></strong><br />
If you don&#8217;t want to create template configuration file, you can write necessary information into ExcelRange metadata as the following.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;
<span style="color: #0000ff;">using</span> JanaBiz.Common.Serialize;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data.Boat
{
    [Serializable]
    <strong>[ExcelRange("ROOT", "B5", "EQ10", "RowRangeService")]</strong>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">BoatRace</span>
    {
        <span style="color: #0000ff;">public</span> BoatRace()
        {
        }

        <strong>[ExcelRange("HEADER", "CX4", "DF48", "BlockRangeService")]</strong>
        <span style="color: #0000ff;">public</span> BoatRaceHeader HeaderData = <span style="color: #0000ff;">new</span> BoatRaceHeader();

        <strong>[ExcelRange("LIST", "BZ4", "CK48", "ColumnListRangeServiceRL")]</strong>
        <span style="color: #0000ff;">public</span> SerializableList&lt;BoatRaceRecord&gt; itemDataList =
           <span style="color: #0000ff;">new</span> SerializableList&lt;BoatRaceRecord&gt;();

        <strong>[ExcelRange("RESULT", "H4", "Q48", "BlockRangeService")]</strong>
        <span style="color: #0000ff;">public</span> BoatRaceResult ResultData = <span style="color: #0000ff;">new</span> BoatRaceResult();
    }
}</pre>
</div>
<p>Then  set parameter of method ParseTemplate(params bool[] usingConfig) to false,  handler.ParseTemplate(false);</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;

<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Handler;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Config;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Data;
<span style="color: #0000ff;">using</span> OpenXmlDemoData;

<span style="color: #0000ff;">namespace</span> TemplateConvertDemo
{
    <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">Program</span>
    {
        <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> Main(<span style="color: #2b91af;">string</span>[] args)
        {
            <span style="color: #008000;">//create your handler </span>
            IOpenXmlHandler handler = <span style="color: #0000ff;">new</span> OpenXmlHandler();

            <span style="color: #008000;">//tell ExcelTDF which ITemplateService is used to </span>
            <span style="color: #008000;">//get template file and template range configuration</span>
            handler.GetTemplateService&lt;LocalTemplateService&gt;();

            <span style="color: #008000;">//tell ExcelTDF which IDataProviderManager and </span>
            <span style="color: #008000;">//what data model is used to data              </span>
            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                <span style="color: #0000ff;">new</span> OpenXmlDemoData.Data.RowRangeServiceData1());

            <span style="color: #008000;">//set template id to identify which template is used</span>
            handler.TemplateId = <span style="color: #a31515;">"RowRangeServiceTest"</span>;

            <span style="color: #008000;">//parse your template </span>
            <strong>handler.ParseTemplate(<span style="color: #0000ff;">false</span>);</strong>

            <span style="color: #008000;">//parse your data </span>
            handler.ParseWorkbook(<span style="color: #0000ff;">null</span>);

            <span style="color: #008000;">//get parsed document</span>
            <span style="color: #2b91af;">byte</span>[] doc = handler.GetParsedDocument();

            <span style="color: #008000;">//release some resource</span>
            handler.Close();
        }
    }
}</pre>
</div>
<p><strong>4. <a name="4">Service</a></strong></p>
<p>ExcelTDF provides many range service to process template range as what you want to. Range service are the implementation class of IExcelRangeService and set in template range configuration file. Simultaneously ExcelTDF provides some custom cell services and function services. As explained on the chapter of Custom service variable, cell services and function services has the writing format as the same as Excel formula. Custom cell services are used to perform special processing like barcode, page break and so on, there are no result returned. Function service does some special processing and returns function result as string. Simply, range service is used to process template range, custom service is used to process template cells.</p>
<p><strong>4.1. <a name="4.1">IExcelRangeService</a></strong><br />
Default range service is configured in Spring.NET objects file included in ExcelTDF package as resource file. Service name which is called ServiceId in template range is object id that is upper case and lower case sensitive.<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">&lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"RowRangeService"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.Service.RowRangeService, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>/&gt;</pre>
</div>
<p>OpenXmlContext class provides some static methods to get ids of different services. You can get all range service ids by<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">OpenXmlContext.GetRangeServiceIds();</pre>
</div>
<p>ExcelTDF full versions provides following range services.<br />
<strong> </strong><br />
	<strong><a href="#4.1.1"> . RowRangeService</a></strong><br />
	<strong><a href="#4.1.2"> . RowListRangeService</a></strong><br />
	<strong><a href="#4.1.3"> . RowCloneRangeService</a></strong><br />
	<strong><a href="#4.1.4"> . ComplexRowListRangeService</a></strong><br />
	<strong><a href="#4.1.5"> . ComplexRowCloneRangeService</a></strong><br />
	<strong><a href="#4.1.6"> . BlockRangeService</a></strong><br />
	<strong><a href="#4.1.7"> . BlockRowListRangeService</a></strong><br />
	<strong><a href="#4.1.8"> . ComplexBlockRowListRangeService</a> </strong><br />
	<strong><a href="#4.1.9"> . ColumnListRangeService</a></strong><br />
	<strong><a href="#4.1.10"> . ColumnListRangeServiceRL</a></strong><br />
	<strong><a href="#4.1.11"> . ColumnCloneRangeService</a></strong><br />
	<strong><a href="#4.1.12"> . ColumnCloneRangeServiceRL</a></strong><br />
	<strong><a href="#4.1.13"> . ComplexColumnListRangeService</a></strong><br />
	<strong><a href="#4.1.14"> . ComplexColumnListRangeServiceRL</a></strong><br />
	<strong><a href="#4.1.15"> . ComplexColumnCloneRangeService</a></strong><br />
	<strong><a href="#4.1.16"> . ComplexColumnCloneRangeServiceRL</a></strong><br />
	<strong><a href="#4.1.17"> . MultiplePageRangeService</a></strong><br />
	<strong><a href="#4.1.18"> . BlockRowCloneRangeService</a></strong><br />
	<strong><a href="#4.1.19"> . BlockColumnCloneRangeService</a></strong><br />
<strong> </strong></p>
<p><strong>4.1.1. <a name="4.1.1">RowRangeService</a></strong><br />
RowRangeService is the simplest service whose range is specified by top row index and bottom row index. RowRangeService replaces the variables in template range with data value in RangeData of IRangeDataProvider. If you specify range by cell name of LeftTop and RightBottom, the variables outside the specified column will not be processed.<br />
The template range specified with this service is able to have child ranges. Generally, the worksheet&#8217;s root range is usually specified by this service.</p>
<p><strong>4.1.2. <a name="4.1.2">RowListRangeService</a></strong><br />
RowListRangeService is used to show a data list whose first element is specified by top row index and bottom row index. RowListRangeService requires you design well-formatted rows for all element in list. The template variable between top row and bottom row will be repeatedly processed until the last element of list. If you specify range by cell name of LeftTop and RightBottom, the variables outside the specified column will not be processed. The range specified service as RowListRangeService can not have child ranges (ExcelTDF not process any child ranges even child range is specified in template range configuration file). see <a href="#4.1.4">ComplexRowListRangeService</a><br />
In template, one element of list maybe have several excel rows as a logical unit. For example, if you specified template range from top row 8 to  bottom row 10, your logical unit is (10-8+1)=3 rows. Assume your data list size is 5, all data will be outputted from row 8 to row 8+3*5-1=22.  If you specify the StartIndex and PageSize in template range configuration, the elements from StartIndex to StartIndex+PageSize will be outputted. If StartIndex + PageSize is greater than the size of list, service outputs to the last element of list. The format of all output logical rows must be the same as the first element rows except that the template variable is only written in the first element rows. The best way is that you copy all cells in the first element several times until your list&#8217;s max size. Make sure cells exist in worksheet. At sometime the cell without text (blank cell ) might not be created in worksheet by Open XML even the cells is shown. See the following diagram of RowListRangeService example.  In template range configuration first element is defined from row index is from 8 to 10. list has max size 5.</p>
<p><a href="/wp-content/uploads/2010/09/t-rowlistservice2.png"><img class="aligncenter size-large wp-image-365" title="t-rowlistservice" src="/wp-content/uploads/2010/09/t-rowlistservice2-1024x516.png" alt="" width="640" height="322" /></a></p>
<p><strong>4.1.3. <a name="4.1.3">RowCloneRangeService</a></strong><br />
RowCloneRangeService is one of usually used service. RowCloneRangeService is used to show data list too. The different from RowListRangeService is RowCloneRangeService don&#8217;t have to set format for each elements except of first element rows. RowCloneRangeService clones cells in first element rows and add them in the below. This is very useful, you don&#8217;t worry about the list size and are able to design template simply.  After cloned row are added into document, the row index of other range and the cell name of formula will be changed, ExcelTDF will recalculate row index about them again. The RowCloneRangeService can not have child ranges as the same as RowListRangeService.<br />
The following is an example. At the bottom of template, there are a Excel formula of =SUM(E21:L25) and a pull down cell. After template is processed, 99 logical unit rows are cloned. The logical row size is 3, so the number of changed rows is 99*3=297. Let us see the formula in the result diagram, SUM(E21:L25) is changed to SUM(E318:L324) and the pull down cell also is moved from row 21 to row 318 too. If RowCloneRangeService is used, the row index of objects on the below of RowCloneRangeService range will be changed automatically, you don&#8217;t have to do any work to correct row index, ExcelTDF does all for you.</p>
<p><a href="/wp-content/uploads/2010/09/t-rowrangeservice2.png"><img class="aligncenter size-full wp-image-375" title="t-rowrangeservice2" src="/wp-content/uploads/2010/09/t-rowrangeservice2.png" alt="" width="823" height="417" /></a></p>
<p>The result processed by RowCloneRangeService is shown in the following.</p>
<p><a href="/wp-content/uploads/2010/09/d-rowclonerange.png"><img class="aligncenter size-full wp-image-373" title="d-rowclonerange" src="/wp-content/uploads/2010/09/d-rowclonerange.png" alt="" width="820" height="612" /></a></p>
<p><strong>4.1.4. <a name="4.1.4">ComplexRowListRangeService</a></strong><br />
ComplexRowListRangeService is a list service like RowListRangeService. The difference between ComplexRowListRangeService and RowListRangeService is that the element of ComplexRowListRangeService&#8217;s list data is able to include child ranges and child range is able to be any range type. RowListRangeService&#8217;s element is not able to include child ranges. Because ComplexRowListRangeService is also a list service, you must design the format for all elements in list as the same way as RowListRangeService. See the following template file, template range configuration and data model. The first element of ComplexRowListRangeService is from C4 to BJ22 and named as PARENTLIST1, other elements are well-designed as the same as the first element. In the element there is a RowListRangeService which is from C8 to BE10 and named as CHILDLIST1. CHILDLIST1&#8242;s maximum data size is 5 in first element of  PARENTLIST1.</p>
<p><a href="/wp-content/uploads/2010/09/t-complexrowlistrange.png"><img class="aligncenter size-full wp-image-383" title="t-complexrowlistrange" src="/wp-content/uploads/2010/09/t-complexrowlistrange.png" alt="" width="804" height="623" /></a></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span>
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span> &gt;
    <span style="color: #008000;">&lt;!-- sheet 1 --&gt;</span>
      &lt;object id=<span style="color: #a31515;">"ComplexRowListRangeServiceTest_SHEET1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
        &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ROOT"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"A1"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"CK275"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
           	&lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
           		&lt;ref object=<span style="color: #a31515;">"CRLRS_PARENTLIST1"</span>/&gt;
        	&lt;/list&gt;
        &lt;/property&gt;
      &lt;/object&gt;

       &lt;object id=<span style="color: #a31515;">"CRLRS_PARENTLIST1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
        &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"PARENTLIST1"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"C4"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BJ22"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"ComplexRowListRangeService"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
           	&lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        		&lt;ref object=<span style="color: #a31515;">"CRLRS_CHILDLIST1"</span>/&gt;
        	&lt;/list&gt;
        &lt;/property&gt;
      &lt;/object&gt;

      &lt;object id=<span style="color: #a31515;">"CRLRS_CHILDLIST1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
        &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"CHILDLIST1"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"C8"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BE10"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowListRangeService"</span>/&gt;
      &lt;/object&gt;
&lt;/objects&gt;</pre>
</div>
<p><a href="/wp-content/uploads/2010/09/d-complexrowlistrange.png"><img class="aligncenter size-full wp-image-384" title="d-complexrowlistrange" src="/wp-content/uploads/2010/09/d-complexrowlistrange.png" alt="" width="825" height="781" /></a></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;
<span style="color: #0000ff;">using</span> JanaBiz.Common.Serialize;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data
{

    [ExcelRange("ROOT")]
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">ComplexRowListRangeServiceData</span>
    {
        [ExcelRange("PARENTLIST1")]
        <span style="color: #0000ff;">public</span> SerializableList&lt;RoomTypeList1&gt; MasterDoorList1 = <span style="color: #0000ff;">new</span> SerializableList&lt;RoomTypeList1&gt;();

    }
}</pre>
</div>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data
{
    <span style="color: #008000;">/// &lt;summary&gt;</span>
    <span style="color: #008000;">/// </span>
    <span style="color: #008000;">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">RoomTypeList1</span>
    {
        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// variable</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        [Excel("部屋数1")]
        <span style="color: #0000ff;">public</span> <span style="color: #2b91af;">string</span> HouseNumber=<span style="color: #a31515;">"12"</span>;

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Child list range </span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        [ExcelRange("CHILDLIST1")]
        <span style="color: #0000ff;">public</span> IList&lt;RowRangeServiceData1&gt; MasterDoorChildList = <span style="color: #0000ff;">new</span> List&lt;RowRangeServiceData1&gt;();

    }
}</pre>
</div>
<p><strong>4.1.5. <a name="4.1.5">ComplexRowCloneRangeService</a></strong><br />
ComplexRowCloneRangeService is a list clone service like RowCloneRangeService. The difference between ComplexRowCloneRangeService and RowCloneRangeService is that the element of ComplexRowCloneRangeService&#8217;s list data is able to include child ranges and child range is able to be any range type. RowCloneRangeService&#8217;s element is not able to include child ranges. See the following template file, template range configuration and data model. Using ComplexRowCloneRangeService, your template design becomes very simple. As the same as service of RowCloneRangeService, you don&#8217;t have to copy the format for each element rows in the list. Following example is explained on the above of Template range example 3.<br />
Let&#8217;s see more detail. ComplexRowCloneRangeService processes the range named PARENTLIST1 from B5 to BJ11, which has a RowCloneRangeService range from C8 to BE10 with color of green named CHILDLIST1.</p>
<p>The cell AA11&#8242;s template variable expression is #C{S4=SUM(SHⅡ本体)}, it is  in the range of PARENTLIST1. The variable name is S4 and referenced variable is SHⅡ本体 which is in the child range of CHILDLIST1. In the first element of PARENTLIST1, the child list has 5 elements, so the variable cells of SHⅡ本体 is AA8,AA11,AA14,AA17,AA20 and the result of formula is =SUM(AA8,AA11,AA14,AA17,AA20). Please see the other variables on the template S1, S1, S2..S10,S11, their behavior are the same as S4.</p>
<p>The cell  C11 in the range of PARENTLIST1 is normal formula, you can see it is become =SUM(L23:BE23), because row index is changed. It is the sum of S1..S11.</p>
<p>See the cells of AZ15, BE15, they are the variables expression #C{=SUM(S10)} and #C{=SUM(NWS本体)}. These two variables are in the range of ROOT. See the result on the diagram and what formula they have been changed to.</p>
<p><a href="/wp-content/uploads/2010/09/t-complexrowclonerange2.png"><img class="aligncenter size-full wp-image-401" title="t-complexrowclonerange" src="/wp-content/uploads/2010/09/t-complexrowclonerange2.png" alt="" width="962" height="375" /></a></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">&lt;?xml version=<span style="color: #a31515;">"1.0"</span> encoding=<span style="color: #a31515;">"utf-8"</span>?&gt;
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span> &gt;
  &lt;!-- sheet 1 --&gt;
  &lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"ComplexRowCloneRangeServiceTest_SHEET1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"ROOT"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"Top"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"1"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"Bottom"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"18"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"RowRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;<span style="color: #0000ff;">ref</span> <span style="color: #2b91af;">object</span>=<span style="color: #a31515;">"CRCRS_PARENTLIST1"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af;">object</span>&gt;

  &lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"CRCRS_PARENTLIST1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"PARENTLIST1"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"B5"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"BJ11"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"ComplexRowCloneRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;<span style="color: #0000ff;">ref</span> <span style="color: #2b91af;">object</span>=<span style="color: #a31515;">"CRCRS_CHILDLIST1"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af;">object</span>&gt;

  &lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"CRCRS_CHILDLIST1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"CHILDLIST1"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"C8"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"BE10"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"RowCloneRangeService"</span>/&gt;
  &lt;/<span style="color: #2b91af;">object</span>&gt;

&lt;/objects&gt;</pre>
</div>
<p><a href="/wp-content/uploads/2010/09/d-complexrowclonerange.gif"><img class="alignleft size-full wp-image-397" title="d-complexrowclonerange" src="/wp-content/uploads/2010/09/d-complexrowclonerange.gif" alt="" width="960" height="720" /></a><br />
<a href="/wp-content/uploads/2010/09/d-complexrowclonerange-21.png"><img class="aligncenter size-full wp-image-405" title="d-complexrowclonerange-2" src="/wp-content/uploads/2010/09/d-complexrowclonerange-21.png" alt="" width="939" height="502" /></a></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data
{

    [ExcelRange("ROOT")]
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">ComplexRowCloneRangeServiceData</span>
    {
        <span style="color: #0000ff;">public</span> ComplexRowCloneRangeServiceData()
        {
            CreateDataForDemo();
        }

        [ExcelRange("PARENTLIST1")]
        <span style="color: #0000ff;">public</span> IList&lt;RoomTypeList1&gt; MasterDoorList1 = <span style="color: #0000ff;">new</span> List&lt;RoomTypeList1&gt;();

    }
}</pre>
</div>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data
{
    <span style="color: #008000;">/// &lt;summary&gt;</span>
    <span style="color: #008000;">/// </span>
    <span style="color: #008000;">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">RoomTypeList1</span>
    {
        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// variable</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        [Excel("部屋数1")]
        <span style="color: #0000ff;">public</span> <span style="color: #2b91af;">string</span> HouseNumber=<span style="color: #a31515;">"12"</span>;

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Child list range </span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        [ExcelRange("CHILDLIST1")]
        <span style="color: #0000ff;">public</span> IList&lt;RowRangeServiceData1&gt; MasterDoorChildList = <span style="color: #0000ff;">new</span> List&lt;RowRangeServiceData1&gt;();

    }
}</pre>
</div>
<p><strong>4.1.6. <a name="4.1.6">BlockRangeService</a></strong><br />
BlockRangeService is as the same as RowRangeService except that the range is specified by cell name. It is a service to process a rectangle region. If you only want to process some special region by service, BlockRangeService is very useful. You can split your complicated template into some simple region to process one by one. The range of RowRangeService is able to be specified by cell name too. In this case RowRangeService has the same action as BlockRangeService. About more detail see RowRangeService.</p>
<p><strong>4.1.7. <a name="4.1.7">BlockRowListRangeService</a></strong><br />
BlockRowListRangeService is the same as RowListRangeService except that the range is specified by cell name. It is also a service to process a rectangle region, but in the region, data is output as list by rows. If the range of RowListRangeService is specified by cell name, RowListRangeService has the same action as BlockRowListRangeService. About more detail, see RowListRangeService.</p>
<p><strong>4.1.8. <a name="4.1.8">ComplexBlockRowListRangeService</a></strong><br />
CpmplexBlockRowListRangeService is a list service whose range is defined by cell name and is able to have child ranges in the list elements. The behavior is like ComplexRowListRangeService. About more detail, see <a href="#4.1.4">ComplexRowListRangeService</a>.</p>
<p><strong>4.1.9-10. <a name="4.1.9">ColumnListRangeService</a> and <a name="4.1.10">ColumnListRangeServiceRL</a></strong><br />
ColumnListRangeService is similar to the RowListRangeService but the range is specified by column index. ColumnListRangeService outputs data from left to right as list. The first element is outputted on the left side of the range. In the opposite, the ColumnListRangeServiceRL outputs data from right to the left. The first element is outputted on the right side of the range. As the same as service of RowListRangeService, you must make sure all element&#8217;s columns have the same format.  See the diagram following, the gray region is processed by ColumnListRangeServiceRL.<br />
<a href="/wp-content/uploads/2010/09/t-columnlistrange.png"><img class="aligncenter size-full wp-image-417" title="t-columnlistrange" src="/wp-content/uploads/2010/09/t-columnlistrange.png" alt="" width="710" height="519" /></a></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">&lt;?xml version=<span style="color: #a31515;">"1.0"</span> encoding=<span style="color: #a31515;">"utf-8"</span>?&gt;
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span>&gt;
  &lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"ColumnListRangeServiceTest_SHEET1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"ROOT"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"B2"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"EQ50"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"RowRangeService"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;<span style="color: #0000ff;">ref</span> <span style="color: #2b91af;">object</span>=<span style="color: #a31515;">"ColumnListRangeServiceTest_1_HEADER"</span> /&gt;
        &lt;<span style="color: #0000ff;">ref</span> <span style="color: #2b91af;">object</span>=<span style="color: #a31515;">"ColumnListRangeServiceTest_1_LIST"</span> /&gt;
        &lt;<span style="color: #0000ff;">ref</span> <span style="color: #2b91af;">object</span>=<span style="color: #a31515;">"ColumnListRangeServiceTest_1_RESULT"</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af;">object</span>&gt;
  &lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"ColumnListRangeServiceTest_1_HEADER"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"HEADER"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"CX4"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"DF48"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"BlockRangeService"</span> /&gt;
  &lt;/<span style="color: #2b91af;">object</span>&gt;
  &lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"ColumnListRangeServiceTest_1_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"BZ4"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"CK48"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"ColumnListRangeServiceRL"</span> /&gt;
  &lt;/<span style="color: #2b91af;">object</span>&gt;
  &lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"ColumnListRangeServiceTest_1_RESULT"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"RESULT"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"H4"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"Q48"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"BlockRangeService"</span> /&gt;
  &lt;/<span style="color: #2b91af;">object</span>&gt;

&lt;/objects&gt;</pre>
</div>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;
<span style="color: #0000ff;">using</span> JanaBiz.Common.Serialize;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data.Boat
{
    [Serializable]
    [ExcelRange("ROOT")]
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">BoatRace</span>
    {
        <span style="color: #0000ff;">public</span> BoatRace()
        {
        }

        [ExcelRange("HEADER")]
        <span style="color: #0000ff;">public</span> BoatRaceHeader HeaderData = <span style="color: #0000ff;">new</span> BoatRaceHeader();

        [ExcelRange("LIST")]
        <span style="color: #0000ff;">public</span> SerializableList&lt;BoatRaceRecord&gt; itemDataList =
           <span style="color: #0000ff;">new</span> SerializableList&lt;BoatRaceRecord&gt;();

        [ExcelRange("RESULT")]
        <span style="color: #0000ff;">public</span> BoatRaceResult ResultData = <span style="color: #0000ff;">new</span> BoatRaceResult();
    }
}</pre>
</div>
<p><strong>4.1.11-12. <a name="4.1.11">ColumnCloneRangeService</a> and <a name="4.1.12">ColumnCloneRangeServiceRL</a></strong><br />
<a href="/wp-content/uploads/2010/09/t-columnclonerange.png"><img class="alignright size-full wp-image-420" title="t-columnclonerange" src="/wp-content/uploads/2010/09/t-columnclonerange.png" alt="" width="371" height="521" /></a><br />
ColumnCloneRangeService is similar to the RowCloneRangeService but the range is specified by column index. ColumnCloneRangeService clones specified columns and add cloned columns one by one from left to right. In the opposite, the ColumnCloneRangeServiceRL clones specified columns and add cloned columns one by one from right to left like the Japanese newspaper. Using ColumnCloneRangeService you don&#8217;t have to copy all elements format as ColumnListRangeService. After processed, column index of some ranges, formulas, objects will be recalculated and moved automatically.</p>
<p>The result is shown in the following.<br />
<a href="/wp-content/uploads/2010/09/d-columnclonerange.png"><img class="aligncenter size-full wp-image-424" title="d-columnclonerange" src="/wp-content/uploads/2010/09/d-columnclonerange.png" alt="" width="702" height="510" /></a></p>
<p><strong>4.1.13-14. <a name="4.1.13">ComplexColumnListRangeService</a> and <a name="4.1.14">ComplexColumnListRangeServiceRL</a></strong><br />
ComplexColumnListRangeService is a list service like ColumnListRangeService. The difference between ComplexColumnListRangeService and ColumnListRangeService is that the element of ComplexColumnListRangeService’s list data is able to include child ranges and child range is able to be any range type. ColumnListRangeService’s element is not able to include child ranges. Because ComplexColumnListRangeService is also a list service, you must design the format for all elements in list as the same way as ColumnListRangeService. If in the element of ComplexColumnListRangeService there is a child range using ColumnListRangeService, make sure each element’s format is designed well too. See the following template file, template range configuration and data model.</p>
<p>Here ROOT range has two child ranges named TITLE and DATA. TITLE is a BlockRangeService and has one child range SIMAI which is processed by service BlockRowListRangeService. Let us see DATA range in detail. DATA range is processed by ComplexColumnListRangeService which has four child ranges; those of them are processed by BlockRowListRangeService. To understand how it works, please check the each child range&#8217;s region. ComplexColumnListRangeService adds the data from left to right. In the contrary, ComplexColumnListRangeServiceRL processes the data from right to left.</p>
<p>The following is the part of template.</p>
<p><a href="/wp-content/uploads/2010/09/t-complexcolumnlistrange2.png"><img class="aligncenter size-full wp-image-431" title="t-complexcolumnlistrange" src="/wp-content/uploads/2010/09/t-complexcolumnlistrange2.png" alt="" width="749" height="817" /></a></p>
<p>Here is the template range configuration file.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span>
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span>&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_SHEET1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ROOT"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"A1"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"IR147"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_ROOT_TITLE"</span> /&gt;
        &lt;ref object=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_ROOT_DATA"</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_ROOT_TITLE"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"TITLE"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B2"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"K147"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRangeService"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_TITLE_SIMAI"</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_TITLE_SIMAI"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"SIMAI"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B32"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"B46"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_ROOT_DATA"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"DATA"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L2"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"U147"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"ComplexColumnListRangeService"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_NAME_LIST"</span> /&gt;
        &lt;ref object=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_DA_LIST"</span> /&gt;
        &lt;ref object=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_BAJYU_LIST"</span> /&gt;
        &lt;ref object=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_DA2_LIST"</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_NAME_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"NAME_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L32"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"L33"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_DA_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"DA_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L58"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"S59"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_BAJYU_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"BAJYU_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L66"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"U81"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_DA2_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"DA2_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L120"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"T121"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
&lt;/objects&gt;</pre>
</div>
<p>The result processed by ComplexColumnListRangeService is shown in the following.<br />
<a href="/wp-content/uploads/2010/09/d-complexcolumnlistrange.png"><img class="aligncenter size-full wp-image-433" title="d-complexcolumnlistrange" src="/wp-content/uploads/2010/09/d-complexcolumnlistrange.png" alt="" width="683" height="819" /></a></p>
<p><strong>4.1.15-16. <a name="4.1.15">ComplexColumnCloneRangeService</a> and <a name="4.1.16">ComplexColumnCloneRangeServiceRL</a></strong><br />
<a href="/wp-content/uploads/2010/09/t-complexcolumnclonerange.png"><img class="alignright size-full wp-image-438" title="t-complexcolumnclonerange" src="/wp-content/uploads/2010/09/t-complexcolumnclonerange.png" alt="" width="206" height="826" /></a><br />
ComplexColumnCloneRangeService is a list clone service like ColumnCloneRangeService. The difference between ComplexColumnCloneRangeService and ColumnCloneRangeService is that the element of ComplexColumnCloneRangeService’s list data is able to include child ranges and child range is able to be any range type. ColumnCloneRangeService’s element is not able to include child ranges. See the following template file, template range configuration and data model. Using ComplexColumnCloneRangeService, your template design becomes very simple. As the same as service of ColumnCloneRangeService, you don’t have to copy the format for each element rows in the list. Here we use ComplexColumnCloneRangeServiceRL to process the range of DATA, the cloned columns are added into the left of range DATA from right to left. The range of DATA has four child ranges. The child range of BAJYU_LIST has three elements; the first element region is from B66 to K81. Please check the output result. The column index of formulas and other objects in the right of range DATA will be changed, ExcelTDF automatically searches these objects and changes the column index of them.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span>
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span>&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnCloneRangeServiceTest_SHEET1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ROOT"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"A1"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"Q148"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"CCCRST_1_TITLE"</span> /&gt;
        &lt;ref object =<span style="color: #a31515;">"CCCRST_1_DATA"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"CCCRST_1_TITLE"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"TITLE"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L2"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"U147"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRangeService"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"CCCRST_1_SIMAI"</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"CCCRST_1_SIMAI"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"SIMAI"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L32"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"U33"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;  

  &lt;object id=<span style="color: #a31515;">"CCCRST_1_DATA"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"DATA"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B2"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"K147"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"ComplexColumnCloneRangeServiceRL"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"CCCRST_1_DA_LIST"</span> /&gt;
        &lt;ref object=<span style="color: #a31515;">"CCCRST_1_BAJYU_LIST"</span> /&gt;
        &lt;ref object=<span style="color: #a31515;">"CCCRST_1_DA2_LIST"</span> /&gt;
        &lt;ref object=<span style="color: #a31515;">"CCCRST_1_NAME_LIST"</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"CCCRST_1_DA_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"DA_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"C58"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"I59"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"CCCRST_1_BAJYU_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"BAJYU_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B66"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"K81"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"CCCRST_1_DA2_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"DA2_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B120"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"K121"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"CCCRST_1_NAME_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"NAME_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B32"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"K33"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"CCCRST_SHEET2"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ROOT"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"A1"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BP41"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"CCCRST_SHEET3"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ROOT"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"A1"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BP41"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span> /&gt;
  &lt;/object&gt;
&lt;/objects&gt;</pre>
</div>
<p>Following is the result document processed by ComplexCiolumnCloneRangeService.</p>
<p><a href="/wp-content/uploads/2010/09/d-complexcolumnclonerange.png"><img class="aligncenter size-full wp-image-446" title="d-complexcolumnclonerange" src="/wp-content/uploads/2010/09/d-complexcolumnclonerange.png" alt="" width="732" height="821" /></a></p>
<p><strong>4.1.17. <a name="4.1.17">MultiplePageRangeService</a></strong><br />
MultiplePageRangeService is created to process some complicated reports or excel documents which has multiple different page designs. Sometimes we want to create a report which has page header, page footer, report header and report footer. In ExcelTDF, you can considered them as some ranges. In fact, using RowRangeService or BlockRowRangeService, you can output header and footer information easily. If your document or report has only one page, you can do your design using services explained on the above. By assembling those services, ExcelTDF is able to output various documents and reports as what you want. If your report has more pages that all of them are the same design, you can use ComplexRowCloneRangeService or ComplexRowListRangeService to output your report page by page.  In this case, a page is an element of list. MultiplePageRangeService provides ability for creating document and report which has different page design while a list data might be outputted across all pages. Usually we want to output some summary information into the first page or last page, the detail information page by page. Depending on the size of list data, the number of pages to be outputted will be variable. MultiplePageRangeService controls these behaviors according to the properties set in the template range configuration file. MultiplePageRangeService is able to process document and report which has two or three different page designs.</p>
<p>Let us see following template, which has two reports, owner sales report and parking sales report. In the template, owner sales report has three different pages and parking sales report has one page. We want to output owner report and parking report for one owner in one worksheet. One owner maybe has a lot of parking, we need to output parking name, parking sales amount as one line for each parking in the owner report and output parking sales amount detail data in the parking report.</p>
<p>Download template <a href="/wp-content/uploads/2010/09/SalesReport1.xlsx">SalesReport</a></p>
<p><a href="/wp-content/uploads/2010/09/t-multitemplatepagerange.png"><img class="aligncenter size-full wp-image-455" title="t-multitemplatepagerange" src="/wp-content/uploads/2010/09/t-multitemplatepagerange.png" alt="" width="1236" height="608" /></a></p>
<p>Parking sales report template page is omitted.</p>
<p>The following is template range configuration file, download <a href="/wp-content/uploads/2010/09/SalesReport.zip">SalesReport</a><br />
In the worksheet, there are two child ranges, and they are owner report and parking report named OWNER_REPORT, PARKING_REPORT. Owner report range has three page child ranges, OWNER_PAGE1, OWNER_PAGE2, OWNER_PAGE3. For three page ranges, there is a list range of sales amount for each parking.  Assume the owner has 56 parkings, the list size will be 56. In the template configuration, the PageSize of the range PARK_DATA_LIST in OWNER_PAGE1, OWNER_PAGE2, OWNER_PAGE3 is 15, so the owner report will be output 4 pages. The property of IsRepeat in internal page OWNER_PAGE2, which is set to true, means this page is able to output repeated. ExcelTDF controls output behavior based on those properties. PARK_DATA_LIST range is outputted across all pages, this behavior is controlled by property of IsCrosssPage.  Besides owner report, each parking detail data is outputed as one page, thus in the worksheet we output owner report as 4 pages and parking report as 56 pages.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">&lt;?xml version="1.0" encoding="utf-8" ?&gt;</span>
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span> &gt;
  <span style="color: #008000;">&lt;!-- sheet 1 --&gt;</span>
  &lt;object id=<span style="color: #a31515;">"SalesReport_SHEET1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"SALES_REPORT"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B1"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BG209"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"OwnerReport"</span>/&gt;
        &lt;ref object=<span style="color: #a31515;">"ParkReport"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"OwnerReport"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"OWNER_REPORT"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B1"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BG150"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"MultiplePageRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"OwnerPage1"</span>/&gt;
        &lt;ref object=<span style="color: #a31515;">"OwnerPage2"</span>/&gt;
        &lt;ref object=<span style="color: #a31515;">"OwnerPage3"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"OwnerPage1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"OWNER_PAGE1"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span>   value=<span style="color: #a31515;">"B1"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BG50"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span>   value=<span style="color: #a31515;">"RowRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"ParkData1"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"ParkData1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"PARK_DATA_LIST"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B24"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BG24"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowListRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"PageSize"</span> value=<span style="color: #a31515;">"15"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"IsCrossPage"</span> value=<span style="color: #a31515;">"true"</span>/&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"OwnerPage2"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span>   value=<span style="color: #a31515;">"OWNER_PAGE2"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span>     value=<span style="color: #a31515;">"B51"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"AT100"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span>   value=<span style="color: #a31515;">"ComplexRowCloneRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"IsRepeat"</span>    value=<span style="color: #a31515;">"true"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"ParkData2"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"ParkData2"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"PARK_DATA_LIST"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B74"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"AJ74"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowListRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"PageSize"</span> value=<span style="color: #a31515;">"15"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"IsCrossPage"</span> value=<span style="color: #a31515;">"true"</span>/&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"OwnerPage3"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span>   value=<span style="color: #a31515;">"OWNER_PAGE3"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span>     value=<span style="color: #a31515;">"B101"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"AT150"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span>   value=<span style="color: #a31515;">"RowRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"ParkData3"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"ParkData3"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"PARK_DATA_LIST"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B124"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"AJ124"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowListRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"PageSize"</span> value=<span style="color: #a31515;">"15"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"IsCrossPage"</span> value=<span style="color: #a31515;">"true"</span>/&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"ParkReport"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"PARK_REPORT"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B151"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"AT209"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"ComplexRowCloneRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"AdditionItems"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"AdditionItems"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ADDITIONS"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B192"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"AJ192"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span>/&gt;
  &lt;/object&gt;

&lt;/objects&gt;</pre>
</div>
<p>Download the result of report  <a href="/wp-content/uploads/2010/09/SalesReport2.xlsx">SalesReport result</a></p>
<p>The following is a part of data model.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using JanaBiz.OpenXml;

namespace OpenXmlDemoData.Data
{
    /// &lt;summary&gt;
    /// sales report
    /// &lt;/summary&gt;
    [ExcelRange("SALES_REPORT")]
    public class SalesReportData
    {
        #region constructor

        public SalesReportData()
        {
        }

        #endregion

        /// &lt;summary&gt;
        /// all parking data of owner
        /// &lt;/summary&gt;
        [ExcelRange("OWNER_REPORT")]
        public OwnerSalesReport ownerReport = new OwnerSalesReport();

        /// &lt;summary&gt;
        /// sales data of parking
        /// &lt;/summary&gt;
        [ExcelRange("PARK_REPORT")]
        public IList&lt;OwnerParkSalesData&gt; ParkList
        {
            get { return ownerReport.ParkList; }
        }
    }
}</pre>
</div>
<p><strong>4.1.18. <a name="4.1.18">BlockRowCloneRangeService</a></strong><br />
BlockRowCloneRangeService is similar to the RowCloneRangeService. The difference is that BlockRowCloneRangeService clones only cells from specified top row to bottom row between specified columns, so the row index of cells that is between the specified columns and row index is greater than the bottom row will be moved after cloned rows are added.<br />
On the other hand, the RowCloneRangeService clones cells from specified top row to bottom row without the limitation of column and moves all cell&#8217;s index below the range itself after the cloned rows are added.</p>
<p><a href="/wp-content/uploads/2010/09/t-blockrowclonerange.png"><img class="aligncenter size-full wp-image-597" title="t-blockrowclonerange" src="/wp-content/uploads/2010/09/t-blockrowclonerange.png" alt="" width="684" height="558" /></a></p>
<p>The result is shown in the following, you can see the range B3 and K4 is cloned and added on the below. The cells that the column index is between column B and K and the row is greater than 4 are moved.</p>
<p><a href="/wp-content/uploads/2010/09/d-blockrowclonerange.png"><img class="aligncenter size-full wp-image-598" title="d-blockrowclonerange" src="/wp-content/uploads/2010/09/d-blockrowclonerange.png" alt="" width="692" height="601" /></a></p>
<p><strong>4.1.19. <a name="4.1.19">BlockColumnCloneRangeService</a></strong><br />
BlockColumnCloneRangeService is similar to the ColumnCloneRangeService. The difference is that BlockColumnCloneRangeService clones only cells from specified left column to right column between specified rows, so the column index of cells that is between the specified rows and greater than the right column will be moved after cloned columns are added.<br />
On the other hand, the ColumnCloneRangeService clones columns from specified left column to right column without row limitation, the columns index that is greater than the right column will be changed after cloned columns is added.</p>
<p><a href="/wp-content/uploads/2010/09/t-blockcolumnclonerange.png"><img class="aligncenter size-full wp-image-601" title="t-blockcolumnclonerange" src="/wp-content/uploads/2010/09/t-blockcolumnclonerange.png" alt="" width="780" height="524" /></a></p>
<p>The result is shown in the following, you can see the range B3 and C23 is cloned and added on the right. The cells that row is  between row 3 and 23 and column is greater than C are moved.</p>
<p><a href="/wp-content/uploads/2010/09/d-blockcolumnclonerange.png"><img class="aligncenter size-full wp-image-603" title="d-blockcolumnclonerange" src="/wp-content/uploads/2010/09/d-blockcolumnclonerange.png" alt="" width="898" height="517" /></a></p>
<p><strong>4.2. <a name="4.2">IExcelCellService &amp; IExcelFunctionService</a></strong><br />
In ExcelTDF, one of the most flexible functionality is that you can create your own custom service. Custom service lets you control your cell output in the template design, that is similar to the excel function. Custom service has two types. The implementation class of IExcelCellService is custom cell service while the implementation class of IExcelFunctionService is custom function service. Cell service has no return result, in the contrary, function service return a string as result. In the custom service, the parameter can be template variable, cell name, constant of text or number. The base class of ExcelCellServiceBase provides a lot of methods to get parameter&#8217;s cell name or values. On the above example of MultiplePageRangeService, we used  XSCHECKBOX, XSPAGEBREAK, XSBARCODE cell services and XFPRANGE and XFSRANGE function services. If parameter of service is cell name, the index of cell&#8217;s row and column will be recalculated. If the parameter of service is template variable, then ExcelTDF will search template variable&#8217;s cell name.<br />
ExcelTDF provides following cell services and function services now.</p>
<p><strong>4.2.1. <a name="4.2.1">Cell Service</a></strong></p>
<p><strong>4.2.1.1. <a name="4.2.1.1">XSCHAR</a></strong><br />
Output amount digit by digit.</p>
<p>Format:<br />
%{=XSCHAR(TEXT, 1|LEFT|left|0|RIGHT|right)}<br />
%{=XSCHAR(TEXT, 1|LEFT|left|0|RIGHT|right, LEADING)}<br />
%{=XSCHAR(TEXT, 1|LEFT|left|0|RIGHT|right, LEADING, TAILING)}<br />
where TEXT is a template variable or cell name or constant of number. Second parameter of 1|LEFT|left indicates that output digit from left to right(left alignment) start with the cell of this service. 0|RIGHT|right indicates that output digit from right to left (right alignment) start with the cell of this service. The third and fourth parameter is appended char on the beginning or ending of char, that maybe dollar marker etc.</p>
<p>Example:<br />
%{=XSCHAR(&#8220;123999&#8243;, 0, &#8220;$&#8221;)}, %{=XSCHAR(A4, 1, &#8220;$&#8221;, &#8220;-&#8221;)}</p>
<p><a href="/wp-content/uploads/2010/09/f-xschar1.png"><img class="aligncenter size-full wp-image-480" title="f-xschar" src="/wp-content/uploads/2010/09/f-xschar1.png" alt="" width="537" height="156" /></a></p>
<p><strong>4.2.1.2. <a name="4.2.1.2">XSCHECKBOX</a></strong><br />
Output a checkbox. The checkbox is not a vb control, it is just using some special font.</p>
<p>Format:<br />
%{=XSCHECKBOX(FLAG)}<br />
%{=XSCHECKBOX(FLAG,TEXT)}<br />
where FLAG is a flag to indicate checked or not, 1|true is checked, otherwise not checked. The second parameter of TEXT is a string after checkbox. Both FLAG and TEXT can be a template variable, cell name of constant string, number.</p>
<p>Example:<br />
%{=XSCHECKBOX(PARKTYPE)},  %{=XSCHECKBOX(PARKTYPE, PARKNAME)}<br />
In data model<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">[Excel("PARKTYPE")]
<span style="color: #0000ff;">public</span> <span style="color: #2b91af;">int</span> ParkType

[Excel("PARKNAME")]
<span style="color: #0000ff;">public</span> <span style="color: #2b91af;">string</span> ParkName</pre>
</div>
<p><a href="/wp-content/uploads/2010/09/f-checkbox.png"><img class="aligncenter size-full wp-image-483" title="f-checkbox" src="/wp-content/uploads/2010/09/f-checkbox.png" alt="" width="616" height="100" /></a></p>
<p><strong>4.2.1.3. <a name="4.2.1.3">XSBARCODE</a></strong><br />
XSBARCODE outputs bar code on the specified image. In order to output bar code you must add a image to template where your bar code will be output. Bar code will be output as the same size as image.</p>
<p>Format:<br />
%{=XSBARCODE(IMAGENAME, BARCODETEXT, TYPE)}<br />
%{=XSBARCODE(IMAGENAME, BARCODETEXT, TYPE, SHOW_LABEL)}<br />
IMAGENAME: the image name you have added into template<br />
BARCODETEXT: bar code string, which can be template variable, cell name or constant text, number<br />
TYPE:  bar code type<br />
SHOW_LABEL: 1 or true specify to output string of bar code text.</p>
<p>Following bar code types are supported:<br />
UCC12<br />
UPCA, UPC-A<br />
UCC13, EAN13, EAN-13<br />
Interleaved2of5<br />
Industrial2of5<br />
Standard2of5<br />
LOGMARS<br />
CODE39<br />
CODE39Extended<br />
Codabar<br />
PostNet<br />
ISBN,BOOKLAND<br />
JAN13,JAN-13<br />
UPC_SUPPLEMENTAL_2DIGIT<br />
MSI_Mod10,MSI_2Mod10,MSI_Mod11,MSI_Mod11_Mod10,Modified_Plessey<br />
UPC_SUPPLEMENTAL_5DIGIT,UPCE,UPC-E<br />
EAN8,EAN-8<br />
USD8,CODE11<br />
CODE128,CODE128A<br />
CODE128B,CODE128C<br />
ITF14,CODE93</p>
<p>Example:<br />
%{=XSBARCODE(&#8220;BCODE&#8221;, BARCODENO, &#8220;UPC-A&#8221;)}<br />
BCODE is image name that bar code image will replace it.</p>
<p><a href="/wp-content/uploads/2010/09/f-barcode1.png"><img class="aligncenter size-full wp-image-488" title="f-barcode1" src="/wp-content/uploads/2010/09/f-barcode1.png" alt="" width="621" height="121" /></a></p>
<p><a href="/wp-content/uploads/2010/09/f-barcode2.png"><img class="aligncenter size-full wp-image-489" title="f-barcode2" src="/wp-content/uploads/2010/09/f-barcode2.png" alt="" width="608" height="137" /></a></p>
<p><strong>4.2.1.4. <a name="4.2.1.4">XSPAGEBREAK</a></strong><br />
Add excel page break in the worksheet for document and report printing. XSPAGEBREAK is very useful for more page output.</p>
<p>Format:<br />
%{=XSPAGEBREAK}<br />
%{=XSPAGEBREAK(ROW|CELL|VAR)}<br />
If no parameter is specified , add page break on the row of this service written. If row or cell is specified add page break on the specified row. If template variable is specified, add page break on the row on which template variable is.</p>
<p>Example: %{=XSPAGEBREAK}<br />
On the example of service MultiplePageRangeService, XSPAGEBREAK is added in the template.<br />
XSPAGEBREAK are added on the last row in last page of owner report and parking report. Parking report is a page processed a clone service. When parking page is cloned, the page break will be added on the last row of cloned page.</p>
<p><a href="/wp-content/uploads/2010/09/f-pagebreak.png"><img class="aligncenter size-full wp-image-492" title="f-pagebreak" src="/wp-content/uploads/2010/09/f-pagebreak.png" alt="" width="453" height="673" /></a></p>
<p><strong>4.2.1.5. <a name="4.2.1.5">XSVDLIST</a></strong><br />
Set cell as pull down list. It is the same as the menu of Data/Data Input/List in the Excel.</p>
<p>Format:<br />
%{VAR=XSVDLIST(&#8220;A,B,C&#8221;|AJ12:AJ20|VARIABLE)}<br />
XSVDLIST is some different from services above. The left side variable name is the value of cell in pull down list while the parameter in expression of XSVDLIST is pull down items which is able to be a string with comma separated or cell range or variable which is in the list range. The value of VAR can be referenced by other expression and can be saved back into data model as other variables.</p>
<p>Example:<br />
%{ITEM=XSVDLIST(&#8220;iPod,iPhone,iPad&#8221;)}<br />
In data model:<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">[Excel("ITEM")]
<span style="color: #0000ff;">public</span> <span style="color: #2b91af;">string</span> Item {<span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span>;}</pre>
</div>
<p><a href="/wp-content/uploads/2010/09/f-vdlist.png"><img class="aligncenter size-full wp-image-495" title="f-vdlist" src="/wp-content/uploads/2010/09/f-vdlist.png" alt="" width="466" height="58" /></a></p>
<p><strong>4.2.2. <a name="4.2.2">Function Service</a></strong><br />
Custom function service can be used in expression of custom cell service, other custom function service and Excel formula.</p>
<p><strong>4.2.2.1. <a name="4.2.2.1">XFPRANGE</a></strong><br />
Search variable from specified parent range and return the cell name such as A12 or cell name string such as A12,A13,A14 if variable is in the list. Because that ExcelTDF search variable first from range of itself, then the child ranges, if you have the same variable name in different range, this function maybe useful, you can search variable from your specified range. Usually, in child range you can reference parent range&#8217;s variable directly by this function.</p>
<p>Format:<br />
%{=XFPRANGE(VAR)}<br />
%{=XFPRANGE(VAR, PARENT_LEVEL)}<br />
VAR: template variable to be searched<br />
PARENT_LEVEL: the number of parent hierarchy<br />
second parameter is the specified number from which parent range to search variable. For example, if the second parent is 2, search variable VAR from the parent&#8217;s parent range. If no second parameter is specified, search from parent range</p>
<p>Example:<br />
#C{=SUM(XFPRANGE(FURIKOMI, 1))}<br />
On the above MultiplePageRangeService, in the first page of owner report we want to output total sum of FURIKOMI which is across in the first page, internal page and last page. So we specified search FURIKOMI from parent range, that is OWNER_REPORT which includes all pages. FURIKOMI is a variable in a list, so SUM(XFPRANGE(FURIKOMI, 1)) is the total amount.</p>
<p><strong>4.2.2.2. <a name="4.2.2.2">XFSRANGE</a></strong><br />
Search variable from all brother ranges including itself and return the cell name such as A12 or cell name string such as A12,A13,A14 if variable is in the list.</p>
<p>Format:<br />
%{=XFSRANGE(VAR)}<br />
VAR is the variable to be searched.</p>
<p>Example:<br />
#C{小計=SUM(FURIKOMI)}<br />
#C{合計=SUM(XFSRANGE(小計))}<br />
On the above MultiplePageRangeService, in owner report, each page has a variable named 小計 which is the sum amount of parking in that page and in the last page there is a variable 合計 which is the sum of all 小計 in each page. You can download sales report result on the above to see how it works.</p>
<p><strong>4.2.2.3. <a name="4.2.2.3">XFCELL</a></strong><br />
This is a simple function to get variable&#8217;s cell name and return cell name or cell name string such as A12,A13,A14.</p>
<p>Format:<br />
%{=XFCELL(VAR)}</p>
<p>Example:<br />
%{=XFCELL(ITEM)}</p>
<p><strong>4.2.2.4. <a name="4.2.2.4">XFMATCH</a></strong><br />
XFMATCH is used to search some values from specified searching range, if matched, it returns the cell names or values.</p>
<p>Format:<br />
%{XFMATCH(SEARCH_VALUES,SEARCH_RANGE)<br />
%{XFMATCH(SEARCH_VALUES,SEARCH_RANGE, PARENT_HIERARCHY)<br />
SEARCH_VALUES:  the values to be searched. which  can be a variable, cell name such as AJ12 or AJ12:AK20, or constant string separated by comma such as &#8220;A,B,C&#8221;. This function searches value by some orders. Assume SEARCH_VALUES is specified as &#8220;A,B,C&#8221;, function will search A first, if found return the result, then B, then C.<br />
SEARCH_RANGE:  the search range which can be a variable, cell name, or any constant string.<br />
PARENT_HIERARCHY:  Specify from which template range to search, 1 is the parent, 2 is the parent&#8217;s parent template range.</p>
<p>Example:<br />
#{=CONCATENATE(XFOFFSET(XFMATCH(&#8220;◎,○,▲&#8221;, 本紙, 1), 0, 1), &#8220;=&#8221;, XFOFFSET(XFMATCH(&#8220;○,▲,△&#8221;, 本紙, 1), 0, 1), XFOFFSET(XFMATCH(&#8220;△&#8221;, 本紙, 1), 0, 1))}<br />
In the example of ColumnCloneRangeService, we used function as above to search the cell which has one of values  ◎,○,▲. You can see the function is used in Excel formula expression.</p>
<p><strong>4.2.2.5. <a name="4.2.2.5">XFOFFSET</a></strong><br />
Get cell name with the specified offset. This function is like excel formula function OFFSET.</p>
<p>Format:<br />
%{=XFOFFSET(VAR,ROW,COL,PARENT_HIERARCHY)}<br />
VAR:  variable to be searched, which is a template variable.<br />
ROW:  row offset number<br />
COL:  column offset number<br />
PARENT_HIERARCHY: Specify from which template range to search, 1 is the parent, 2 is the parent&#8217;s parent template range.</p>
<p>Example:<br />
#{=CONCATENATE(XFOFFSET(XFMATCH(&#8220;◎,○,▲&#8221;, 本紙, 1), 0, 1), &#8220;=&#8221;, XFOFFSET(XFMATCH(&#8220;○,▲,△&#8221;, 本紙, 1), 0, 1), XFOFFSET(XFMATCH(&#8220;△&#8221;, 本紙, 1), 0, 1))}</p>
<p><strong>4.3. <a name="4.3">How to create your service</a></strong><br />
ExcelTDF provides mechanism to create your own range service, cell service and function service. The three interfaces are used to let you create your service easily.  These interfaces are IExcelRangeService, IExcelCellService and IExcelFunctionService.</p>
<p><strong>4.3.1. <a name="4.3.1">How to create template range service, IExcelRangeService</a></strong><br />
See the example of MyRowRangeService which do the same works as RowRangeService.</p>
<p><strong>4.3.1.1. <a name="4.3.1.1">Create IExcelRangeService implementation class</a></strong><br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;
<span style="color: #0000ff;">using</span> log4net;
<span style="color: #0000ff;">using</span> JanaBiz.Common.Serialize;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Data;

<span style="color: #0000ff;">namespace</span> myservice
{
    <span style="color: #008000;">/// &lt;summary&gt;</span>
    <span style="color: #008000;">/// Process excel range defined by top row, and bottom row.</span>
    <span style="color: #008000;">/// Template variable are replaced by value in data model.</span>
    <span style="color: #008000;">/// This is simple range. worksheet root range is this type.</span>
    <span style="color: #008000;">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">MyRowRangeService</span> : ExcelRangeServiceBase, IExcelRangeService
    {
        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Logger</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">readonly</span> ILog logger = LogManager.GetLogger(<span style="color: #0000ff;">typeof</span>(MyRowRangeService));

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">///  constructor</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #0000ff;">public</span> MyRowRangeService()
            : <span style="color: #0000ff;">base</span>()
        {
        }

        <span style="color: #0000ff;">#region interface method</span>

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Parse specified worksheet using data provider</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;param name="sheetIndex"&gt;&lt;/param&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> Parse(<span style="color: #2b91af;">int</span> sheetIndex)
        {
            <span style="color: #008000;">//if no data, not processing </span>
            <span style="color: #0000ff;">if</span> (ExcelRange == <span style="color: #0000ff;">null</span> || ExcelRange.DataProvider == <span style="color: #0000ff;">null</span>) <span style="color: #0000ff;">return</span>;

            <span style="color: #008000;">//get data provider</span>
            IRangeDataProvider dataProvider = ExcelRange.DataProvider;

            <span style="color: #008000;">//reset mapping info</span>
            ExcelRange.DataMapping.Clear();

            <span style="color: #008000;">//get mapping info from data provider</span>
            SerializableDictionary&lt;<span style="color: #2b91af;">string</span>, ExcelAttribute&gt; dmp = dataProvider.GetMappingData(dataProvider[0]);
            ExcelRange.DataMapping.Add(dmp);

            <span style="color: #008000;">//set data values into mapped variables</span>
            SetNewCellValues(ExcelRange, dmp, ExcelRange.Top, ExcelRange.Bottom, 0, 0);

            <span style="color: #008000;">//no row or column index moved or changed</span>
            ExcelRange.ChangedRowCount = 0;

            <span style="color: #008000;">//process flag of this range</span>
            ExcelRange.Parsed = <span style="color: #0000ff;">true</span>;
        }

        <span style="color: #0000ff;">#endregion</span>

    }
}</pre>
</div>
<p><strong>4.3.1.2. <a name="4.3.1.2">Add your service object into configuration file</a></strong><br />
In your application configuration file, there is Spring.NET configuration section of object; add your object as following.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">  &lt;!-- my range service--&gt;
&lt;objects&gt;
&lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"<strong>MyRowRangeService</strong>"</span> type=<span style="color: #a31515;">"myservice.MyRowRangeService, Your_Assembly(dll)"</span>  singleton=<span style="color: #a31515;">"false"</span>/&gt;
&lt;/objects&gt;</pre>
</div>
<p><strong>4.3.1.3. <a name="4.3.1.3">Set your service into your template range configuration</a></strong></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">&lt;?xml version="1.0" encoding="shift_jis"?&gt;</span>
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span> &gt;
  <span style="color: #008000;">&lt;!-- sheet 1 --&gt;</span>
  &lt;object id=<span style="color: #a31515;">"MyRowRangeService_SHEET1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ROOT"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"Top"</span> value=<span style="color: #a31515;">"8"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"Bottom"</span> value=<span style="color: #a31515;">"10"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"MyRangeService"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"MyRangeService"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"MYRANGE"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L8"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BE10"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"<strong>MyRowRangeService</strong>"</span>/&gt;
  &lt;/object&gt;
&lt;/objects&gt;</pre>
</div>
<p>That is all, now ExcelTDF will call your service of MyRowRangeService to process specified range in your template configuration file.</p>
<p><strong>4.3.2. <a name="4.3.2">How to create your custom cell service, IExcelCellService</a></strong><br />
See the example of MyVDListCellService which performs the same work as XSVDLIST</p>
<p><strong>4.3.2.1. <a name="4.3.2.1">Create implementation class of IExcelCellService</a></strong></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Collections;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;

<span style="color: #0000ff;">using</span> DocumentFormat.OpenXml;
<span style="color: #0000ff;">using</span> DocumentFormat.OpenXml.Packaging;
<span style="color: #0000ff;">using</span> DocumentFormat.OpenXml.Spreadsheet;
<span style="color: #0000ff;">using</span> log4net;

<span style="color: #0000ff;">using</span> JanaBiz.ExcelFormulaParser;

<span style="color: #0000ff;">namespace</span> myservice
{
    <span style="color: #008000;">/// &lt;summary&gt;</span>
    <span style="color: #008000;">/// My validate list cell service </span>
    <span style="color: #008000;">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">MyVDListCellService</span> : ExcelCellServiceBase, IExcelCellService
    {
        <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">readonly</span> ILog logger = LogManager.GetLogger(<span style="color: #0000ff;">typeof</span>(MyVDListCellService));

        <span style="color: #0000ff;">public</span> MyVDListCellService()
            : <span style="color: #0000ff;">base</span>()
        {
        }

        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> Parse(<span style="color: #2b91af;">int</span> sheetIndex)
        {
            <span style="color: #008000;">//1: get parameters</span>
            Parameters = GetExpressionParameters(ExprTreeNode, sheetIndex);

            <span style="color: #008000;">//2: check exists function variable in template </span>
            <span style="color: #0000ff;">if</span> (!ExcelRange.IsMyVariable(CellData.VarName))
            {
                <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ServiceException(<span style="color: #0000ff;">this</span>, <span style="color: #a31515;">"E_NO_VDLIST_VAR"</span>, CellData.VarName);
            }

            <span style="color: #008000;">//3: check if no paramter</span>
            <span style="color: #0000ff;">if</span> (Parameters.Count == 0)
            {
                <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ServiceException(<span style="color: #0000ff;">this</span>, <span style="color: #a31515;">"E_NO_PARAM"</span>);
            }

            <span style="color: #008000;">//4: check if parameter is empty</span>
            <span style="color: #2b91af;">string</span> listValues = Parameters[0].Param;
            <span style="color: #0000ff;">if</span> (<span style="color: #2b91af;">string</span>.IsNullOrEmpty(listValues))
            {
                <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ServiceException(<span style="color: #0000ff;">this</span>, <span style="color: #a31515;">"E_EMPTY_PARAM"</span>);
            }

            <span style="color: #008000;">//5: parameter type check</span>
            <span style="color: #0000ff;">switch</span> (Parameters[0].ParamType)
            {
                <span style="color: #008000;">//if it is variable</span>
                <span style="color: #0000ff;">case</span> ParamType.VARIABLE:
                    IList&lt;<span style="color: #2b91af;">string</span>&gt; cells = GetReferencesOfVariable(listValues, sheetIndex, ExcelRange, ListIndex);
                    <span style="color: #0000ff;">if</span> (cells == <span style="color: #0000ff;">null</span> || cells.Count == 0)
                    {
                        <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ServiceException(<span style="color: #0000ff;">this</span>, <span style="color: #a31515;">"E_VAR_NOT_FOUND"</span>, listValues);
                    }
                    <span style="color: #2b91af;">string</span>[] cellrefs = OpenXmlSpreadsheet.CreateMergeCellname(WorksheetPart, cells.ToArray());
                    <span style="color: #0000ff;">if</span> (cellrefs.Length &gt; 1)
                    {
                        listValues = <span style="color: #2b91af;">string</span>.Format(<span style="color: #a31515;">"{0}:{1}"</span>, cellrefs[0], cellrefs[1]);
                    }
                    <span style="color: #0000ff;">break</span>;
                <span style="color: #008000;">//if it is cell reference</span>
                <span style="color: #0000ff;">case</span> ParamType.CELL:
                <span style="color: #008000;">//if it is text </span>
                <span style="color: #0000ff;">case</span> ParamType.TEXT:
                    <span style="color: #0000ff;">break</span>;
            }

            <span style="color: #008000;">//do your work here </span>
            <span style="color: #008000;">//set data validate list formula1            </span>
            SetCellValue(CellData.DataType, CellData.CellName, CellData.CellValue);
            OpenXmlSpreadsheet.SetDataValidateFormula1(WorksheetPart, CellData.CellName, listValues);
        }
    }
}</pre>
</div>
<p><strong>4.3.2.2. <a name="4.3.2.2">Add your service object into configuration file</a></strong><br />
In your application configuration file, there is Spring.NET configuration section of object, add your object as following.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">  &lt;!-- my cell service--&gt;
&lt;objects&gt;
&lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"<strong>MYVDLIST</strong>"</span> type=<span style="color: #a31515;">"myservice.MyVDListCellService, Your_Assembly(dll)"</span>  singleton=<span style="color: #a31515;">"false"</span>/&gt;
&lt;/objects&gt;</pre>
</div>
<p>Now you can use MYVDLIST in your template. ExcelTDF will parse template and build your cell service MYVDLIST by calling your created class.</p>
<p><a href="/wp-content/uploads/2010/09/f-myvdlist.png"><img class="aligncenter size-full wp-image-512" title="f-myvdlist" src="/wp-content/uploads/2010/09/f-myvdlist.png" alt="" width="508" height="57" /></a></p>
<p><strong>4.3.3. <a name="4.3.3"> How to create your custom function service, IExcelFunctionService</a></strong><br />
Custom function service is the same as custom cell service except that function service must return a result. The result is set in property of FunctionResultValue. See the following example; it does the same work as the XFCELL function explained above.</p>
<p><strong>4.3.3.1. <a name="4.3.3.1"> Create your implementation class of IExcelFunctionService</a></strong></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Collections;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;

<span style="color: #0000ff;">using</span> log4net;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;

<span style="color: #0000ff;">namespace</span> myservice
{
    <span style="color: #008000;">/// &lt;summary&gt;</span>
    <span style="color: #008000;">/// Get variable's cell name </span>
    <span style="color: #008000;">/// %{=XFCELL(VAR)}</span>
    <span style="color: #008000;">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">MyCellFunctionService</span> : ExcelCellServiceBase, IExcelFunctionService
    {
        <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">readonly</span> ILog logger = LogManager.GetLogger(<span style="color: #0000ff;">typeof</span>(MyCellFunctionService));

        <span style="color: #0000ff;">public</span> MyCellFunctionService()
            : <span style="color: #0000ff;">base</span>()
        {
        }

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// do your work here </span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;param name="sheetIndex"&gt;&lt;/param&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> Parse(<span style="color: #2b91af;">int</span> sheetIndex)
        {
            Parameters = GetExpressionParameters(ExprTreeNode, sheetIndex);

            <span style="color: #008000;">//1: no parameter check</span>
            <span style="color: #0000ff;">if</span> (Parameters.Count == 0)
                <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ServiceException(<span style="color: #0000ff;">this</span>, <span style="color: #a31515;">"E_NO_PARAM"</span>);

            <span style="color: #008000;">//2: get cellname parameter</span>
            <span style="color: #2b91af;">string</span> var1 = Parameters[0].Param;

            <span style="color: #008000;">//3: empty parameter check</span>
            <span style="color: #0000ff;">if</span> (<span style="color: #2b91af;">string</span>.IsNullOrEmpty(var1))
                <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ServiceException(<span style="color: #0000ff;">this</span>, <span style="color: #a31515;">"E_EMPTY_PARAM"</span>);

            <span style="color: #008000;">//4: parameter type</span>
            <span style="color: #0000ff;">switch</span> (Parameters[0].ParamType)
            {
                <span style="color: #008000;">//it is a variable</span>
                <span style="color: #0000ff;">case</span> ParamType.VARIABLE:
                    FunctionResultValue = GetVariableResultAsString(
                        GetReferencesOfVariable(var1, sheetIndex, ExcelRange, ListIndex));
                    <span style="color: #0000ff;">break</span>;
                <span style="color: #008000;">//it is a cell name</span>
                <span style="color: #0000ff;">case</span> ParamType.CELL:
                    FunctionResultValue = var1;
                    <span style="color: #0000ff;">break</span>;
                <span style="color: #008000;">//for others</span>
                <span style="color: #0000ff;">default</span>:
                    <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ServiceException(<span style="color: #0000ff;">this</span>, <span style="color: #a31515;">"E_NOT_CELLNAME"</span>, var1);
            }
        }
    }
}</pre>
</div>
<p><strong>4.3.3.2. <a name="4.3.3.2">Add your service object into configuration file</a></strong><br />
In your application configuration file, there is Spring.NET configuration section of object, add your object as following.<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">  &lt;!-- my function service--&gt;
&lt;objects&gt;
&lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"<strong>MYCELL</strong>"</span> type=<span style="color: #a31515;">"myservice.MyCellFunctionService, Your_Assembly(dll)"</span>  singleton=<span style="color: #a31515;">"false"</span>/&gt;
&lt;/objects&gt;</pre>
</div>
<p>Now you can use MYCELL in your template. ExcelTDF will parse template and build your cell service MYCELL by calling your created class.</p>
<p><a href="/wp-content/uploads/2010/09/f-mycell.png"><img class="aligncenter size-full wp-image-517" title="f-mycell" src="/wp-content/uploads/2010/09/f-mycell.png" alt="" width="516" height="56" /></a><!--:--><!--:ja--><strong><a href="/post/ExcelTDF#1">1. What is ExcelTDF </a></strong></p>
<p><strong><a href="/post/ExcelTDF#2">2. Introduction</a></strong></p>
<p><strong><a name="3">3. Overview</a></strong></p>
<p><strong>3.1. <a name="3.1">How to use ExcelTDF in your solution</a></strong><br />
As the following diagram shows, ExcelTDF is able to run at server-side, client-side and client-only. The interface and usage is the same wherever the ExcelTDF is running. For the both server-side and client-side, the templates of excel are managed on the server. The difference between server-side and client-side is that client-side provides auto saving functionality.<br />
<a href="/wp-content/uploads/2010/09/aspnet-diagram.png"><img class="aligncenter size-large wp-image-804" title="aspnet-diagram" src="/wp-content/uploads/2010/09/aspnet-diagram-1024x594.png" alt="" width="640" height="371" /></a><br />
<a href="/wp-content/uploads/2010/09/clientside-diagram.png"><img class="aligncenter size-large wp-image-805" title="clientside-diagram" src="/wp-content/uploads/2010/09/clientside-diagram-1024x625.png" alt="" width="640" height="390" /></a></p>
<p><strong>3.2. <a name="3.2">ExcelTDF Core classes</a></strong><br />
ExcelTDF does almost of work for you by some core classes. <strong>Excel2007TemplateParser </strong>and <strong>Excel2007DataParser </strong> are the two of these classes. But the convenient way for you is using implementation classes of <strong>IExcelHandler </strong>or <strong>IOpenXmlHandler </strong>interface named <strong>ExcelHandler</strong>, <strong>OpenXmlHandler</strong>. Excel2007TemplateParser, as the name of class, analyzes the template file and load the <strong>template range</strong> configuration file. After template is analyzed, template parser will know the mapping relationship of variables/cells and <strong>template range</strong> tree. Excel2007DataParser analyzes your data class structure and its meta data or SQL data. Metadata named <strong>ExcelRange</strong> and <strong>ExcelAttribute</strong> defines range information and Excel cell variable information. After data is analyzed, Excel2007DataParser will know the data/variable mapping relationship and get <strong>ExcelRange</strong>&#8216;s tree structure that is used to used to  determine how to process template.</p>
<p><a href="/wp-content/uploads/2010/12/ExcelTDF-diagram.png"><img class="aligncenter size-large wp-image-761" title="ExcelTDF-diagram" src="/wp-content/uploads/2010/12/ExcelTDF-diagram-1024x612.png" alt="" width="640" height="382" /></a></p>
<p>	<strong>3.3. <a name="3.3">How to get ExcelTDF work</a></strong><br />
In order to let ExcelTDF work, there are fourth steps to do, the first two steps is only needed to do one time.<br />
	<strong> . Set Configuration</strong><br />
	<strong> . Creating template file by Excel 2007 above and creating template range configuration file. If you use Metadata to define all range information, this step can be omitted</strong><br />
	<strong> . Creating IDataProvider class or Data Model class to get data</strong><br />
	<strong> . Download or open your parsed document or report</strong></p>
<p><strong>3.4. <a name="3.4">Set Configuration</a></strong><br />
When you use ExcelTDF to process template, you should tell ExcelTDF how to get template files and template range configuration files. Your template files and template range configuration files maybe saved as files in specified directory or saved in database or gotten from service.</p>
<p><strong>3.4.1. <a name="3.4.1">Manage templates by files</a></strong><br />
Your template excel file and template range configuration file can be managed on server by files. In ExcelTDF we call it repository. Typically your configuration file is named as Repository.config. It is loaded by ExcelTDF when application starting.<br />
The following is the content of Repository.config. You can add more repositories in this file.</p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%">&lt;?xml version=<span style="color: #a31515">&quot;1.0&quot;</span> encoding=<span style="color: #a31515">&quot;utf-8&quot;</span> ?&gt;
&lt;objects xmlns=<span style="color: #a31515">&quot;http://www.springframework.net&quot;</span>&gt;
  
  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;mydemo&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.Repository.FileSystemRepositoryManager, JanaBiz.OpenXml&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RepositoryName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;myrepository&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;RepositoryUri&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;../../Templates&quot;</span>/&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

&lt;/objects&gt;
</pre>
</div>
<p>On the above, the root repository directory is ../../Templates/myrepository. This is relative path to the executable dll. Certainlly, it is can be any full path. It is also be able to database connection string or others for RepositoryUri.</p>
<p>Usually you can use following two ways to load Repository.config when application starting.</p>
<p>a).  For console application or Windows form application</p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%">[assembly: RegisterRepository(&quot;your_namespace.Repository.config&quot;)]
</pre>
</div>
<p>b). For all type of application </p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%">            OpenXmlContext.RegisterRepository(<span style="color: #a31515">&quot;your_namespace.Repository.config&quot;</span>);
</pre>
</div>
<p><br/><br/></p>
<p><strong>Refresh your repository</strong><br />
If your template range configuration file is changed or you added, removed some lines in template.xml and resource.xml, you must refresh context to load new configuration information. ExcelTDF provides a method in class OpenXmlContext to reload repositories.</p>
<p><strong>3.4.2. <a name="3.4.2">Manage templates by database</a></strong><br />
If you get template file and template range configuration file from database or other stream resource, you don&#8217;t have to set repository information . The resource handler&#8217;s protocol named &#8220;memory&#8221; will load your template file, template range configuration file into context. In order to do this work, you must create a class that implements the interface <strong>ITemplateService</strong>. By following code, you can set your database template service which implements ITemplateService. This tells ExcelTDF MyDatabaseTemplateService is used to get template file and template range configuration, similar to handler.GetTemplateService(&#8220;myconfig&#8221;) which use LocalTemplateService to load template files in the repository. There are no access limitation when using database to manage templates, you can do yourself.<br />
<!-- HTML generated using hilite.me -->
<div class="div-example">
<pre style="margin: 0; line-height: 125%">ExcelHandler handler = <span style="color: #0000ff">new</span> ExcelHandler();

<span style="color: #008000">//implements ITemplateService interface</span>
MyDatabaseTemplateService service = <span style="color: #0000ff">new</span> MyTemplateService();
handler.SetTemplateServiceservice(service);

<span style="color: #008000">//or</span>
MyDatabaseTemplateService service = handler.GetTemplateServiceservice&lt;MyDatabaseTemplateService &gt;();
</pre>
</div>
<p><strong>3.4.3. <a name="3.4.3">Get templates from web service</a></strong><br />
If your templates managed on server and you use IExcelHandler on client side, you can tell ExcelTDF getting templates by web service. In this case, your web service must implement methods defined in ITemplateService but <strong>don&#8217;t need to implement the interface</strong> of ITemplateService. This feature gives you capability of managing your templates by web service very simple. Following is some code.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">ExcelHandler handler = <span style="color: #0000ff;">new</span> ExcelHandler();
...
TemplateServiceSoapClient templateService = handler.GetTemplateService&lt;TemplateServiceSoapClient&gt;();</pre>
</div>
<p><br/><br />
<strong>3.5. <a name="3.5">Template File</a></strong><br />
<strong>keywords</strong>:<br />
       <strong> . General variable</strong><br />
       <em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;${VAR1}</em><br />
       <strong> . Formula variable</strong><br />
       <em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#{=SUM(A20*SUM(VAR1)+VAR2)}</em><br />
       <strong> . Custom service variable</strong><br />
       <em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%{=XSPAGEBEAK}</em><br />
       <strong> . Parameter variable</strong><br />
       <em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;?{VAR=PARAM1}</em><br />
       <strong> . Template Range binding</strong><br />
       <em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ ExcelRange("MyRange", "A1", "Z20", "RowRangeService")]</em><br />
       <strong> . Excel Variable binding </strong><br />
       <em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Excel("VAR1"......)]</em></p>
<p><strong>3.5.1. <a name="3.5.1">Variables in Template</a></strong><br />
When template processing, IExcel2007TemplateParser will search variables in the template and collect mapped information of variable and cell name. As the result, variables are mapped into data value after Excel2007DataParser parsed document. Template variable is a name of an arbitrary text string, whose formats are defined as ${..}, #{..}, %{..}, ?{..} four types.</p>
<p><strong>3.5.1.1. <a name="3.5.1.1">General variable: ${VAR1}</a></strong><br />
VAR1 is a general variable.  ExcelTDF will replace the the variable with the value in data model or SQL query data or some others depending on what data provider is used. For the data model, here is an example.</p>
<p><a href="/wp-content/uploads/var1.png"><img src="/wp-content/uploads/var1.png" alt="" title="var1" width="203" height="65" class="aligncenter size-full wp-image-1139" /></a></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%">[ExcelRange(&quot;ROOT&quot;, &quot;A1, &quot;C3&quot;, &quot;RowRangeService&quot;)]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">MyTestMode</span>

    [Excel(&quot;VAR1&quot;)]
    <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> MyName {<span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }
}
</pre>
</div>
<p>As the above, after processed, the variable of ${VAR1} will be replaced by value of MyName property in the data mode of MyTestMode. If ${VAR1} is in list range and MyTestMode is element of list, The ${VAR1} will be the value of each element MyTestMode in the list.</p>
<p><strong>3.5.1.2. <a name="3.5.1.2">Formula variable: #{VAR2=SUM(VAR1, CJ12, 20)}</a></strong><br />
Formula variable is an Excel formula expression variable. After processed, the cell of formula variable will be a normal Excel formula function expression, such as =SUM(R12) etc. In the above expression, the left side of the equal &#8220;=&#8221; is variable name VAR2, and the right side is expression. Here VAR2&#8242;s value is the sum of VAR1. ExcelTDF will search VAR1 variable and compute the cell name of VAR1 automatically. In the expression of formula variable, you can use both normal cell name, such as  CJ12, AR12:AR20, $AR$20 and variable name. ExcelTDF is able to identify expression variable type of cell name, variable, text and number. For example, assume that VAR1 is in the list range and the cells are AK20,AK21,AK22 after range is processed, the variable of #{VAR2=SUM(VAR1, CJ12, 20)} will be explained as the sum of =SUM(AK20,AK21,AK22, CJ12, 20).<br />
<a href="/wp-content/uploads/var2.png"><img src="/wp-content/uploads/var2.png" alt="" title="var2" width="319" height="64" class="aligncenter size-full wp-image-1142" /></a></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">#{VAR2=SUM(VAR1, CJ12, 20)} --&gt; =SUM(AK20,AK21,AK22, CJ12, 20)</pre>
</div>
<div class="div-example">
<pre style="margin: 0; line-height: 125%">[ExcelRange(&quot;ROOT&quot;, &quot;A1, &quot;C3&quot;, &quot;RowRangeService&quot;)]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">MyTestMode</span>

    [Excel(&quot;VAR1&quot;)]
    <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> MyName {<span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }

    [Excel(&quot;VAR2&quot;)]
    <span style="color: #0000ff">public</span> <span style="color: #2b91af">double</span> Sum {<span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }
}
</pre>
</div>
<p>Formula variable expression is able to has sub expression. Generally no limitation on the formula expression, you can use as normal excel file. Here is complicated one. The variable&#8217;s name is MYNO, in the expression, no other variables referenced.</p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">#{MYNO=IF(ISERROR(MATCH("◎", R6:BZ6, 0))=FALSE,
    HLOOKUP("◎", R6:BZ9, 3, FALSE),
    IF(ISERROR(MATCH("○", R6:BZ6, 0))=FALSE,
          HLOOKUP("○", R6:BZ9, 3, FALSE),
          IF(ISERROR(MATCH("▲", R6:BZ6, 0))=FALSE,
                 HLOOKUP("▲", R6:BZ9, 3, FALSE),
                 IF(ISERROR(MATCH("△", R6:BZ6, 0))=FALSE,
                       HLOOKUP("△", R6:BZ9, 3, FALSE),
                       ""
                       )
                )
          )
    )}</pre>
</div>
<p>The following are also formula variables. In the expression, TRACKNO, FACTOR, QUANTITY, PRICE, BASEPRICE are referenced variables, ExcelTDF will replace them with correct cell names when building formula.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">#{VAR2=CONCATENATE("ABCD",LEFT(TRACKNO,1))}
#{VAR2=SUM(FACTOR*SUM(QUANTITY*PRICE))+ BASEPRICE*15%}</pre>
</div>
<p><strong>If no other variable references VAR2, the name of VAR2 can be omitted.</strong> for example</p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">#{=SUM(FACTOR*SUM(QUANTITY*PRICE))+ BASEPRICE*15%}</pre>
</div>
<p>Certainly, you can use excel formula directly if the cell name is not changed dynamically and don&#8217;t need to reference a variable. ExcelTDF don&#8217;t process them, for example =SUM(12*C12), <strong>this is not a variable</strong>.</p>
<p>In the excel formula variable expression, you can use custom <strong>custom function service</strong> as the same as Excel function. About <strong>custom function service</strong>, please see next section of Custom service variable.</p>
<p><strong>3.5.1.3. <a name="3.5.1.3">Custom service variable: %{VAR3=XFSRANGE(RACENO)}</a></strong><br />
Custom service variable is customized cell service or function service, which is scalable functionality  provided by ExcelTDF. ExcelTDF provides several custom cell services and function services.<br />
You can develop your custom cell service and function service too. Custom services are used to processing special cells or some computing functionality. There are two types of custom services, one is Cell Service which implements interface of IExcelCellService, and another is Function Service which implements interface of IExcelFunctionService. IExcelFunctionService is a sub interface of IExcelCellService. The two types of services are used for different purpose. In order to distinguish from Excel formula functions, cell service name and function service name in ExcelTDF start with XS and XF. In fact the name is the object id defined in the Spring.NET configuration file.</p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%">&lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;XFSRANGE&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.Service.XFSiblingRangeFunctionService, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;
</pre>
</div>
<p><br/><br />
<a href="/wp-content/uploads/var3.png"><img src="/wp-content/uploads/var3.png" alt="" title="var3" width="319" height="61" class="aligncenter size-full wp-image-1146" /></a></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%">[ExcelRange(&quot;ROOT&quot;, &quot;A1, &quot;C3&quot;, &quot;RowRangeService&quot;)]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">MyTestMode</span>

    [Excel(&quot;VAR1&quot;)]
    <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> MyName {<span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }

    [Excel(&quot;VAR2&quot;)]
    <span style="color: #0000ff">public</span> <span style="color: #2b91af">double</span> Sum {<span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }

    [Excel(&quot;VAR3&quot;)]
    <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> No {<span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }

}
</pre>
</div>
<p><br/><br />
If no other variable references VAR3, the name of VAR3 can be omitted. for example<br />
<!-- HTML generated using hilite.me -->
<div class="div-example">
<pre style="margin: 0; line-height: 125%">%{=XFSRANGE(VAR1)}
</pre>
</div>
<p><br/><br />
<strong>3.5.1.3.1. <a name="3.5.1.3.1">Cell Service</a></strong><br />
Cell service does some special processing, for example, showing a barcode.  Cell service has no result returned. Following are some cell services provided by ExcelTDF.</p>
<p>	XSBARCODE:  output a barcode<br />
	XSCHECKBOX: output a checkbox<br />
	XSPAGEBREAK: add page break of excel<br />
	XSVDLIST:   showing cell as pulldown list</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">%{=XSBARCODE("BCODE", BARCODE_NO, "UPC-A")}
%{=XSCHECKBOX(1, PLAYER)}
%{=XSPAGEBREAK(20)}
%{AAA=XSVDLIST(RESULT)}</pre>
</div>
<p>On the above, in the expression, BARCODE_NO, PLAYER, RESULT is referenced template variables.</p>
<p><strong>3.5.1.3.2. <a name="3.5.1.3.2">Function Service</a></strong><br />
Function Service does some processing and returns the result as string. Depending on what you want to do, the function&#8217;s result maybe is variable&#8217;s cell name or variable&#8217;s value. The function is able to have sub expression in which another custom function might be called. The following is a example.<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">%{=XFOFFSET(XFMATCH("◎,○,▲", RACENO, 1), 0, 1)}</pre>
</div>
<p>In the above, custom function XFMATCH is called, and the result of XFMATCH  becomes a parameter of custom function XFOFFSET.</p>
<p>Because custom function returns the result, the custom function can be called in expression of Excel formula variable expression, such as the below.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">#{=CONCATENATE(XFOFFSET(XFMATCH("◎,○,▲", RACENO, 1), 0, 1), "=", XFOFFSET(XFMATCH("○,▲,△", RACENO, 1), 0, 1), XFOFFSET(XFMATCH("△", RACENO, 1), 0, 1))}</pre>
</div>
<p>In the above, in excel formula function expression CONCATENATE, custom function XFOFFSET and XFMATCH are called.</p>
<p><em><strong>Note</strong>: Custom function service can not call excel function as sub expression because the custom function service and cell service are processed only one time while workbook are loading, not in the period of running.</em></p>
<p><strong>3.5.1.4. <a name="3.5.1.4">Parameter variable:  ?{VAR2}</a></strong><br />
Parameter variable is used to specify parameter when searching the data. This is run-time functionality like CrystalReport, in the version 1.0.0.0, no support for parameter variable.</p>
<p><strong>3.5.1.5. <a name="3.5.1.5">Data type of variable</a></strong><br />
In ExcelTDF, you can specify data type forcibly. You just need to add a special char after the leading of letter. N is number type, C is currency type, D is date type. If no N, C, D specified, the variable considered as general string type. In the version of 1.0.0.0, type N, C will forcibly set cell type as NUMBER, D is now processed as string type.  Don&#8217;t confuse the data type with data output format. Output format such as $#,###,### is set by excel on the template designing, data type just tell excel the output data is whether a number or not etc. The following is examples.</p>
<p>General variable ${VAR1}, $N{VAR1}, $C{VAR1}, $D{VAR1}<br />
${VAR1}:   output as type of string or standard<br />
$N{VAR1}: output should be a number and ExcelTDF set the cell&#8217;s type to Number<br />
$C{VAR1}: output should be currency and ExcelTDF set the cell&#8217;s type to Number<br />
$D{VAR1}: output should be date and ExcelTDF does as string or standard in the version 1.0.0.0</p>
<p>The same rules are used for formula variables, custom service variables and parameter variables.<br />
Formula variable:  #{..}, #N{..}, #C{..}, #D{..}<br />
Custom service variable:  %{..}, %N{..}, %C{..}, %D{..}<br />
Parameter variable: ?{..}, ?N{..}, ?C{..}, ?D{..}</p>
<p><strong>3.5.1.6. <a name="3.5.1.6">The Range of variable</a></strong><br />
In a range, variable must be unique, but in different range, there is no this limitation. When a variable is referenced by formula or custom service, ExcelTDF try to search the variable and find cell names or values of variable. ExcelTDF search variable by some orders. ExcelTDF always search expression variable first from the range of variable itself. If not found, ExcelTDF then search expression variable from child ranges. Last, try to search expression variable from all. Understanding the searching order will help you to get correct result.</p>
<p><strong>3.5.2. <a name="3.5.2">Template range</a></strong><br />
Template range is an excel range specified by row index or column index or excel cell name. <strong>Range Service Name</strong> must be specified to identify which template range to be processed by ExcelTDF. Template range is defined both by object in Spring.NET configuration file and by Metadata defined in data model. Defined items in template range are the properties of type of class <strong>TemplateRange</strong>.</p>
<p>When you design your template, the first thing is that you should determine how to output data with template. You can determine how many template ranges there are and how to process template ranges according to your data structure. If your data is a list, define a template range as a list service range will simplify your processing. Please see the examples to understand Template Range and Range Services.</p>
<p>Template file is a Excel workbook(*.xlsx). In this version only *.xlsx format is supported. As the known, one workbook might have several worksheets. ExcelTDF splits a worksheet as some ranges which include  some cells to be processed or not. For the cells to be processed,  the cell text might include one or more defined variables. A range might have some child ranges, and child range is able to has its own child ranges too. These range&#8217;s definition information must be specified by template range configuration file or defined by Metadata in data model. So the whole worksheet is considered as a root range, all other ranges are worksheet&#8217;s child or descendant ranges.</p>
<p>See the following diagram. The worksheet root range has three child ranges named R-A, R-E, R-D, and range R-A also has two child range R-B, R-C. From diagram we can see a tree of range.<br />
<a href="/wp-content/uploads/2010/09/template-range.png"><img class="aligncenter size-full wp-image-227" title="template-range" src="/wp-content/uploads/2010/09/template-range.png" alt="" width="824" height="456" /></a></p>
<p>The template range configuration file, simply, we can consider it as TemplateRange class. The all items&#8217; name are TemplateRange&#8217;s properties. The service name used to process range is listed in <a href="#servicenames">service names</a>, You can get all names by call OpenXmlContext&#8217;s GetRangeServiceIds() methods too.</p>
<p>The following is template whose layout is the same as description above.<br />
<a href="/wp-content/uploads/range.png"><img src="/wp-content/uploads/range.png" alt="" title="range" width="420" height="490" class="aligncenter size-full wp-image-1157" /></a></p>
<p>The following is corresponding  template range configuration file.</p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%">&lt;?xml version=<span style="color: #a31515">&quot;1.0&quot;</span> encoding=<span style="color: #a31515">&quot;utf-8&quot;</span>?&gt;
&lt;objects xmlns=<span style="color: #a31515">&quot;http://www.springframework.net&quot;</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;SAMPLE_SHEET1&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;RootRange&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;A1&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;Z51&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;RowRangeService&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ChildRanges&quot;</span>&gt;
      &lt;list element-type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span>&gt;
        &lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;R-A-ID&quot;</span> /&gt;
	&lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;R-E-ID&quot;</span> /&gt;
	&lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;R-D-ID&quot;</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;R-A-ID&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;R-A&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;B3&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;S31&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BlockRangeService&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ChildRanges&quot;</span>&gt;
      &lt;list element-type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span>&gt;
        &lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;R-B-ID&quot;</span> /&gt;
        &lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;R-C-ID&quot;</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;R-E-ID&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;R-E&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;B37&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;S49&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span>  <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BlockRangeService&quot;</span>/&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;
 
  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;R-D-ID&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;R-D&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;U2&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;Y49&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span>  <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BlockRangeService&quot;</span>/&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;R-B-ID&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;R-B&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;C9&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;Q16&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span>  <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BlockRangeService&quot;</span>/&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;R-C-ID&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;R-C&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;B20&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;Q29&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span>  <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BlockRangeService&quot;</span>/&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

&lt;/objects&gt;
</pre>
</div>
<p><br/><br />
The following is model class used to process template above.<br />
<!-- HTML generated using hilite.me -->
<div class="div-example">
<pre style="margin: 0; line-height: 125%">[ExcelRange(&quot;SHEET1&quot;)]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RT</span>
{
	[ExcelRange(&quot;R-A&quot;)]
	<span style="color: #0000ff">public</span> RA ra;
	
	[ExcelRange(&quot;R-D&quot;)]
	<span style="color: #0000ff">public</span> RD rd;

	[ExcelRange(&quot;R-E&quot;)]
	<span style="color: #0000ff">public</span> RE re;
}


<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RA</span>{

	[ExcelRange(&quot;R-B&quot;)]	
	<span style="color: #0000ff">public</span> RB rb;

	[ExcelRange(&quot;R-C&quot;)]
	<span style="color: #0000ff">public</span> RC rc
}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RB</span> {}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RC</span> {}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RD</span> {}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RE</span> {}
	
</pre>
</div>
<p><br/><br />
If you want to define range&#8217;s all information into Metadata to replace template range configuration file, the following is sample of data model.<br />
<!-- HTML generated using hilite.me -->
<div class="div-example">
<pre style="margin: 0; line-height: 125%">[ExcelRange(&quot;SHEET1&quot;, &quot;A1&quot;, &quot;Z51&quot;, &quot;RowRangeService&quot;)]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RT</span>
{
	[ExcelRange(&quot;R-A&quot;, &quot;B3&quot;, &quot;S31&quot;, &quot;BlockRangeService&quot;)]
	<span style="color: #0000ff">public</span> RA ra;
	
	[ExcelRange(&quot;R-D&quot;, &quot;U2&quot;, &quot;Y49&quot;, &quot;BlockRangeService&quot;)]
	<span style="color: #0000ff">public</span> RD rd;

	[ExcelRange(&quot;R-E&quot;, &quot;B37&quot;, &quot;Y49&quot;, &quot;BlockRangeService&quot;)]
	<span style="color: #0000ff">public</span> RE re;
}


<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RA</span>{

	[ExcelRange(&quot;R-B&quot;, &quot;C9&quot;, &quot;Q16&quot;, BlockRangeService&quot;)]	
	<span style="color: #0000ff">public</span> RB rb;

	[ExcelRange(&quot;R-C&quot;, &quot;B20&quot;, &quot;Q29&quot;, &quot;BlockRangeService&quot;)]
	<span style="color: #0000ff">public</span> RC rc
}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RB</span> {}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RC</span> {}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RD</span> {}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RE</span> {}
	
</pre>
</div>
<p><br/><br />
<strong>3.5.2.1. <a name="3.5.2.1">Template range example 1</a></strong><br />
Next let us see how to determine your template range by some examples.<br />
First, see the following most simple example. We just want  to replace the variables between row 8 and row 10, so the worksheet has only one root range from row 8 to row 10.</p>
<p><a href="/wp-content/uploads/template-example11.png"><img src="/wp-content/uploads/template-example11.png" alt="" title="template-example1" width="1247" height="327" class="aligncenter size-full wp-image-1164" /></a></p>
<p>In order to tell ExcelTDF the range&#8217;s information , we write these information into a Spring.NET object xml file as following.<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span>
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span> &gt;
    <span style="color: #008000;">&lt;!-- sheet 1 --&gt;</span>
      &lt;object id=<span style="color: #a31515;">"RowRangeServiceTest_sheet1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
        &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ROOT"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"Top"</span> value=<span style="color: #a31515;">"8"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"Bottom"</span> value=<span style="color: #a31515;">"10"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span>/&gt;
      &lt;/object&gt;
&lt;/objects&gt;</pre>
</div>
<p>On the above, in configuration file, the type of object is always JanaBiz.OpenXml.TemplateRange. TemplateRange has some properties must be specified. These properties are RangeName, ServiceId and range defined by (Top|Left|LeftTop) and (Bottom|Right|RightBottom). If we want to specify range by row index without column limitation, the Top and Bottom property should be set. If we want to specify range by column index without limitation of row index, the Left and Right property should be set. If we want to specify rectangle range with the limitation of row and column, the property LeftTop and RightBottom should be set.</p>
<p>	RangeName: the identifier of the range<br />
	Top/Bottom | Left/Right | LeftTop/RightBottom :  the range specified by row or column or cell name<br />
	ServiceId:  the service name used to process this range. <a href="#servicenames">see service names</a></p>
<p>The object id can be any string but it must be unique in all configuration files, For the worksheet root range, it is best to assign object id as <strong>template id + &#8220;sheet&#8221; + worksheet index </strong>. This will be convenient to ExcelTDF to find worksheet root range object. About some other property please see TemplateRange class API.</p>
<p>For the template above, following is the processed result. Because the service is RowRangeService, it just replaces the variables in specified template range with the data in data model.</p>
<p><a href="/wp-content/uploads/template-example1-result.png"><img src="/wp-content/uploads/template-example1-result.png" alt="ExcelTDF " title="template-example1-result" width="1249" height="323" class="aligncenter size-full wp-image-1166" /></a></p>
<p><strong>3.5.2.2. <a name="3.5.2.2">Template range example 2</a></strong><br />
Following is another template file. In this template file we want to output data as a list. The list&#8217;s element is from row 8 to row 10, let us see how different result will be got.</p>
<p>The template file is shown as following.</p>
<p><a href="/wp-content/uploads/template-example2.png"><img src="/wp-content/uploads/template-example2.png" alt="" title="template-example2" width="1248" height="528" class="aligncenter size-full wp-image-1168" /></a></p>
<p>The template configuration file is shown as following.</p>
<p><!-- HTML generated using hilite.me -->
<div class="div-example">
<pre style="margin: 0; line-height: 125%">&lt;?xml version=<span style="color: #a31515">&quot;1.0&quot;</span> encoding=<span style="color: #a31515">&quot;shift_jis&quot;</span>?&gt;
&lt;objects xmlns=<span style="color: #a31515">&quot;http://www.springframework.net&quot;</span> &gt;
  &lt;!-- sheet 1 --&gt;
  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;RowListRangeServiceTest_SHEET1&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;ROOT&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;Top&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;1&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;Bottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;30&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;RowRangeService&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ChildRanges&quot;</span>&gt;
      &lt;list element-type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span>&gt;
        &lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;RLRSChildList1&quot;</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;RLRSChildList1&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;CHILDLIST1&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;L8&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BN10&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;RowListRangeService&quot;</span>/&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

&lt;/objects&gt;
</pre>
</div>
<p>There are two TemplateRanges in worksheet. The worksheet root range, whose RangeName is ROOT and it has a  child range. Root range is from row 8 to row 22. Child range&#8217;s id is <strong>RLRSChildList1 </strong>and RangeName is CHILDLIST1. Child range is from L8 to BE10. Child range is processed by service of <strong>RowListRangeService </strong>which output data as list with the same format as defined range L8:BE10, Assume your list in the data model has 5 elements, the data of 5 elements will be outputted from L8 to L20.</p>
<p>The following is processed result.</p>
<p><a href="/wp-content/uploads/template-example2-result.png"><img src="/wp-content/uploads/template-example2-result.png" alt="" title="template-example2-result" width="1247" height="527" class="aligncenter size-full wp-image-1170" /></a></p>
<p>If we change the ROOT range&#8217;s row from row 7 to row 20, what will be changed? The variable of ${HouseNumber1} is in the range of ROOT, this variable will be processed. ROOT range&#8217;s ServiceId is RowRangeService, the variable is just replaced by value in data model corresponding to the ROOT range.</p>
<p><strong>3.5.2.3. <a name="3.5.2.3">Template range example 3</a></strong><br />
Next, let us see a some complicated examples. In this example we want to output a list, and the element of list is also a list. We usually bump into this case. As the shown, template design is very simple too. The outer list&#8217;s element is from B5 to BJ11, the inner list&#8217;s element is from C8 to BE10. So the variable of $N{HouseNumber1}, #C{S1=SUM(HBⅡBody)}, #C{=SUM(S10)} etc. are processed by outer list. Inner list size might be different, the service of specified will process them correctly.</p>
<p><a href="/wp-content/uploads/template-example3.png"><img src="/wp-content/uploads/template-example3.png" alt="" title="template-example3" width="1143" height="347" class="aligncenter size-full wp-image-1172" /></a></p>
<p>As the diagram of following, the worksheet has three ranges. Root range of worksheet is from row 1 to 18, which is processed by RowRangeService. The root range has a child range whose id is CRCRS_PARENTLIST1, named PARENTLIST1 and colored with gray. Child range is from B5 to BJ11, which is processed by service of <strong>ComplexRowCloneRangeService</strong>. The service named with prefix of  ComplexXX is used to process list ranges who&#8217;s element has child range. So the part of B5:BJ11 will be cloned list size-1 times. The cloned rows are inserted in the below of the last row BJ<strong>11</strong>, here it is row 12. Because the element of list includes a child range,  whose id is CRCRS_CHILDLIST1 , this range is also a cloned list, the cloned rows is from C8 to BE10, The row of parent range will be changed dynamically. ExcelTDF control ranges processing order, first parent range, then child ranges. If child range is a coned list, parent range&#8217;s row or column will be changed automatically.</p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%">&lt;?xml version=<span style="color: #a31515">&quot;1.0&quot;</span> encoding=<span style="color: #a31515">&quot;utf-8&quot;</span>?&gt;
&lt;objects xmlns=<span style="color: #a31515">&quot;http://www.springframework.net&quot;</span> &gt;
  &lt;!-- sheet 1 --&gt;
  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;ComplexRowCloneRangeServiceTest_SHEET1&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;ROOT&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;Top&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;1&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;Bottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;18&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;RowRangeService&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ChildRanges&quot;</span>&gt;
      &lt;list element-type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span>&gt;
        &lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;CRCRS_PARENTLIST1&quot;</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;CRCRS_PARENTLIST1&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;PARENTLIST1&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;B5&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BJ11&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;ComplexRowCloneRangeService&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ChildRanges&quot;</span>&gt;
      &lt;list element-type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span>&gt;
        &lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;CRCRS_CHILDLIST1&quot;</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;CRCRS_CHILDLIST1&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;CHILDLIST1&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;C8&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BE10&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;RowCloneRangeService&quot;</span>/&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

&lt;/objects&gt;
</pre>
</div>
<p>The result is shown in the following. You can see, the simple template creates complicated data output. There are many patterns you can assemble by provided services in ExcelTDF.</p>
<p><a href="/wp-content/uploads/template-example3-result.png"><img src="/wp-content/uploads/template-example3-result.png" alt="" title="template-example3-result" width="1075" height="697" class="aligncenter size-full wp-image-1173" /></a></p>
<p><strong>3.5.3. <a name="3.5.3">Without template range file</a></strong><br />
If your template doesn’t need to be changed frequently, maybe you don&#8217;t want to create template range configuration file. In this case the template range information can be written in code as metadata of program. If you write range information into code, and your template layout is changed, you must modify your code. The most benefit of using template range configuration file is you don&#8217;t have to change your code if template layout changed.  For the detail, please see next chapter about data provider.</p>
<p><strong>3.6. <a name="3.6">Data Provider and Data Model</a> </strong><br />
ExcelTDF uses two types of interface to control the mapping information. IDataProviderManager controls mapping behavour of IRangeDataProvider and template range, while IRangeDataProvider controls mapping behavour of data field in data model and template variable. Data field maybe is field or property  in data model, or columns of SQL query, or some others.</p>
<p><strong>3.6.1 <a name="3.6.1">The types of data provider manager</a></strong><br />
Each implementation class of IDataProviderManager knows how to map data provider to template range. Actually manager maps RangeData in IRangeDataProvider to template range. RangeData can be data model, DataSet or other data objects. ExcelTDF provides three manager classes.</p>
<p><strong>3.6.1.1. <a name="3.6.1.1">DataModelProviderManager</a></strong><br />
DataModelProviderManager, in which the default DataModelRangeDataProvider is used,  maps data model to template range. ExcelRange and ExcelAttibute(Excel) Attribute classes are used to help ExcelTDF doing those works. The RangeData in DataModelRangeDataProvider is your data model for DataModelProviderManager. In the next you will see how to use them in data model.</p>
<p><strong>3.6.1.2. <a name="3.6.1.2">QueryProviderManager</a></strong><br />
QueryProviderManager let you create document or report by specified SQL query, all template ranges use the same one query data if you use QueryProviderManager. If you are familiar with CrystalReport, creating a query and getting report, this is the similarity functionality.</p>
<p><strong>3.6.1.3. <a name="3.6.1.3">AnyTypeProviderManager</a></strong><br />
AnyTypeProviderManager let you create document or report by any data type. You should create IRangeDataProvider for each template range. If no IRangeDataProvider found, the IRangeDataProvider of parent range will be used. You can specify a data model for a range, SQL query for another range. You can specify SQL query for each range and so on.  It is the most flexible manager.</p>
<p>See the following diagram, it shows the association between template and data.</p>
<p><a href="/wp-content/uploads/2010/09/dataprovider3.png"><img class="aligncenter size-full wp-image-300" title="dataprovider" src="/wp-content/uploads/2010/09/dataprovider3.png" alt="" width="905" height="534" /></a></p>
<p>As you see, ExcelTDF provides various IRangeDataProvider implementation classes, from data mode to usually used database, even SAP. IRangeDataProvider has two methods ReadRangeData() for getting data from database or background service, and WriteRangeData() for saving edited data to database or sending to background service. ExcelTDF maps RangeData in IRangeDataProvider to template range. ExcelTDF provides three IDataProviderManager implementation classes, they are DataModelProviderManager,  QueryProviderManager and  AnyTypeProviderManager. The three data provider managers have the different control behavior and are used in different way. The DataModelProviderManager is the most often used data provider manager. If the RangeData in IRangeDataProvider is data model, not a SQL DataSet and not SAP&#8217;s DataReader, DataModelProviderManager is your suitable selection.</p>
<p><strong>3.6.2 <a name="3.6.2">Data model of Template range example 1</a></strong><br />
In the following, let us see how to use DataModelProviderManager and what your data model should be.<br />
For the Template range example-1 which we discussed on the above, data model is shown in the diagram. Please see the fields that have defined Excel metadata, for example  [Excel("HBⅡBody")], it will map the value of HBⅡBody to the template variable defined as ${HBⅡBody}. Every template variable must have corresponding metadata with the same name in data model. If [Excel("X")] is defined in data model, but no ${X} or #{X=..} or %{X=..} found, &#8220;X&#8221; can be used in formula expression and custom service expression. For example, #{VAR2=SUM(VAR1*X/100)}, X is not a variable in template but a variable in data model. In the same way, the metadata [ExcelRange("ROOT")] tells ExcelTDF that the range information named ROOT in the template range configuration is used for this model, and variables defined in this model by metadata are mapped to template variables in the range named ROOT.</p>
<p><!-- HTML generated using hilite.me -->
<div class="div-example">
<pre style="margin: 0; line-height: 125%"><span style="color: #0000ff">using</span> System;
<span style="color: #0000ff">using</span> System.Xml.Serialization;
<span style="color: #0000ff">using</span> JanaBiz.OpenXml;

<span style="color: #0000ff">namespace</span> OpenXmlDemoData.Data
{

    [ExcelRange(&quot;ROOT&quot;)]
    [Serializable]
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RowRangeServiceData1</span>
    {
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> HouseType;

        [Excel(&quot;HouseNumber1&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> HouseNum = <span style="color: #a31515">&quot;20&quot;</span>;

        [Excel(&quot;HBⅡBody&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">double</span> HBⅡBody;

        [Excel(&quot;VAR2&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> Var2;

        [Excel(&quot;LBⅡBody&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> LBⅡBody;

        [Excel(&quot;KCBody&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> KCBody;

        [Excel(&quot;SHⅡBody&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> SHⅢBody;

        .....
    }
}
</pre>
</div>
<p>Here is the code to parse template and get your document. As you see, after you finished your template design and wrote well your template configuration, the coding is very simple.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;

<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Handler;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Config;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Data;
<span style="color: #0000ff;">using</span> OpenXmlDemoData;

<span style="color: #0000ff;">namespace</span> TemplateConvertDemo
{
    <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">Program</span>
    {
        <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> Main(<span style="color: #2b91af;">string</span>[] args)
        {
            <span style="color: #008000;">//create your handler </span>
            IOpenXmlHandler handler = <span style="color: #0000ff;">new</span> OpenXmlHandler();

            <span style="color: #008000;">//tell ExcelTDF which ITemplateService is used to </span>
            <span style="color: #008000;">//get template file and template range configuration</span>
            handler.GetTemplateService&lt;LocalTemplateService&gt;();

            <span style="color: #008000;">//tell ExcelTDF which IDataProviderManager and </span>
            <span style="color: #008000;">//what data model is used to data              </span>
            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                <span style="color: #0000ff;">new</span> OpenXmlDemoData.Data.RowRangeServiceData1());

            <span style="color: #008000;">//set template id to identify which template is used</span>
            handler.TemplateId = <span style="color: #a31515;">"RowRangeServiceTest"</span>;

            <span style="color: #008000;">//parse your template </span>
            handler.ParseTemplate();

            <span style="color: #008000;">//parse your data </span>
            handler.ParseWorkbook(<span style="color: #0000ff;">null</span>);

            <span style="color: #008000;">//get parsed document</span>
            <span style="color: #2b91af;">byte</span>[] doc = handler.GetParsedDocument();

            <span style="color: #008000;">//release some resource</span>
            handler.Close();
        }
    }
}</pre>
</div>
<p>In the code, creating DataModelProviderManager with parameter of RowRangeServiceData1 will enable manager use default data provider of DataModelRangeDataProvider. In fact, DataModelProviderManager have two constructors with parameter of either data model or IRangeDataProvider when you want use your customized IRangeDataProvider.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">        <span style="color: #0000ff;">public</span> DataModelProviderManager(Object dataModel)

      <span style="color: #0000ff;">public</span> DataModelProviderManager(IRangeDataProvider rootRangeDataProvider)</pre>
</div>
<p>If you want to open parsed workbook into excel in your excel AddIn program directly, ExcelHandler is prepared for you.<br />
The code is shown as the following. The step of coding is the same as the above example. Here we create and initialize handler first, and get template file and template range configuration by web service of TemplateServiceSoapClient. <strong>So your web service should perform the methods of interface ITemplateService, but your service don&#8217;t have to implement the interface of ITemplateService</strong>. This will be helpful for you to reference web service directly.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">        <span style="color: #0000ff;">private</span> ExcelHandler handler = <span style="color: #0000ff;">null</span>;
        <span style="color: #0000ff;">private</span> TemplateServiceSoapClient webService = <span style="color: #0000ff;">null</span>;

        <span style="color: #0000ff;">public</span> RibbonDemo()
        {
            InitializeComponent();
        }

        <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> RibbonDemo_Load(<span style="color: #2b91af;">object</span> sender, RibbonUIEventArgs e)
        {
            InitializeExcelHandler();
        }

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Create and initialize &lt;see cref="IExcelHandler"/&gt;</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> InitializeExcelHandler()
        {
            <span style="color: #008000;">//create IExcelHandler instance</span>
            handler = <span style="color: #0000ff;">new</span> ExcelHandler();

            <span style="color: #008000;">// set excel application </span>
            handler.ExcelApp = Globals.ThisAddIn.Application;

            <span style="color: #008000;">//create or get template service </span>
            webService = handler.GetTemplateService&lt;TemplateServiceSoapClient&gt;();

            <span style="color: #008000;">//create data service </span>
            DataService dataService = <span style="color: #0000ff;">new</span> DataService();

            <span style="color: #008000;">//get excel data event handler</span>
            handler.OnGetDocumentData += dataService.GetDocumentData;

            <span style="color: #008000;">//save excel data event handler</span>
            handler.OnSaveDocumentData += dataService.SaveDocumentData;
        }</pre>
</div>
<p>On the above, we create DataService object which performs OnGetDocumentData event handler for getting data model. Certainly you can assign DataModelProviderManager to handler directly too,  such as<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                <span style="color: #0000ff;">new</span> OpenXmlDemoData.Data.RowRangeServiceData1());</pre>
</div>
<p>Define a event handler is very flexible. First, coding logic to get data for all templates can be put in event handler method. Second, you can override IRangeDataProvider, and get data in your way. The event handler method is show in the below.<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Assign a data provider manager or data range provider to a template for specified template id</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;param name="handler"&gt;&lt;/param&gt;</span>
        <span style="color: #008000;">/// &lt;param name="sheetIndex"&gt;&lt;/param&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> GetDocumentData(IOpenXmlHandler handler, <span style="color: #2b91af;">int</span> sheetIndex)
        {
            <span style="color: #0000ff;">switch</span> (handler.TemplateId)
            {
                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"RowRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            <span style="color: #008000;">// you can get from web service etc., for simple, here just new a data model </span>
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                            <span style="color: #0000ff;">new</span> RowRangeServiceData1());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;
            }
        }</pre>
</div>
<p>Let us see the code about opening parsed document, only several lines. Open() method try to find data provider manager and data provider by event handler of OnGetDocumentData. If event handler exists, it will be called.<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Open parsed workbook of spreadsheet</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;param name="templateId"&gt;&lt;/param&gt;</span>
        <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> OpenDocument(<span style="color: #2b91af;">string</span> templateId)
        {
            <span style="color: #008000;">//close opened workbook before</span>
            handler.Close();

            <span style="color: #008000;">//template id used</span>
            handler.TemplateId = templateId;
            <span style="color: #008000;">//other input parameter for get excel data </span>
            handler.InputData = <span style="color: #0000ff;">null</span>;
            <span style="color: #008000;">//parse template</span>
            handler.ParseTemplate();
            <span style="color: #008000;">//parse workbook and open it in excel or other component</span>
            handler.Open();
        }</pre>
</div>
<p><strong>3.6.3 <a name="3.6.3">Data model of Template range example 2</a></strong><br />
In this example because the root template range has a child range, the data model is also created into two classes hierarchically. RowListRangeServiceData class has metadata [ExcelRange("ROOT")] and its field member ChildList1 has metadata [ExcelRange("CHILDLIST1")]. The names of ROOT and CHILDLIST1 matches the RangeName defined in template range configuration. In template range configuration, the ServiceId of CHILDLIST1 is RowListRangeService, so in the data model of RowListRangeServiceData, the member with metadata  [ExcelRange("CHILDLIST1")], ChildList1  must be a list.</p>
<p><em>ExcelRange binding a data model is associated to template range, and if your template range ServiceId is list related service, data member should be a list type of IList. That is all.</em></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;
<span style="color: #0000ff;">using</span> JanaBiz.Common.Serialize;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data
{
    [Serializable]
    <strong>[ExcelRange("ROOT")]</strong>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">RowListRangeServiceData</span>
    {
        <span style="color: #0000ff;">public</span> RowListRangeServiceData()
        {
            <span style="color: #008000;">//Create data for demo</span>
            <span style="color: #0000ff;">for</span> (<span style="color: #2b91af;">int</span> i = 0; i &lt; 5; i++)
            {
                ChildList1.Add(<span style="color: #0000ff;">new</span> RowRangeServiceData1());
            }
        }

       <strong>[ExcelRange("CHILDLIST1")]</strong>
        <span style="color: #0000ff;">public</span> IList&lt;RowRangeServiceData1&gt; ChildList1 = <span style="color: #0000ff;">new</span> List&lt;RowRangeServiceData1&gt;();

    }
}</pre>
</div>
<p>In OnGetDocumentData event handler we added a piece of coding for getting data model. other works are the same as example-1</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Assign a data provider manager or data range provider to a template for specified template id</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;param name="handler"&gt;&lt;/param&gt;</span>
        <span style="color: #008000;">/// &lt;param name="sheetIndex"&gt;&lt;/param&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> GetDocumentData(IOpenXmlHandler handler, <span style="color: #2b91af;">int</span> sheetIndex)
        {
            <span style="color: #0000ff;">switch</span> (handler.TemplateId)
            {
                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"RowRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            <span style="color: #008000;">// you can get from web service etc., for simple, here just new a data model </span>
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                            <span style="color: #0000ff;">new</span> RowRangeServiceData1());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;

<strong>                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"RowListRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> RowListRangeServiceData());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;
</strong>            }
        }</pre>
</div>
<p><strong>3.6.4 <a name="3.6.4">Data model of Template range example 3</a></strong><br />
In this example, the template range has a list, and list&#8217;s element is also a list. Let us see the data model how to construct.<br />
As you have seen, entry class ComplexRowCloneRangeServiceData has metadata ExcelRange(&#8220;ROOT&#8221;), its member MasterDoorList1  has  metadata  [ExcelRange("PARENTLIST1")], MasterDoorList1 is a list.  MasterDoorList1&#8242;s element is RoomTypeList1 which has a member MasterDoorChildList, and MasterDoorChildList has metadata [ExcelRange("CHILDLIST1")], it is also a list. In the OnGetDocumentData event handler we added code to get data provider manager. For the others no need to change.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;

<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data
{
    <strong>[ExcelRange("ROOT")]</strong>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">ComplexRowCloneRangeServiceData</span>
    {
        <span style="color: #0000ff;">public</span> ComplexRowCloneRangeServiceData()
        {
            CreateDataForDemo();
        }
        <strong>[ExcelRange("PARENTLIST1")]</strong>
        <span style="color: #0000ff;">public</span> IList&lt;RoomTypeList1&gt; MasterDoorList1 = <span style="color: #0000ff;">new</span> List&lt;RoomTypeList1&gt;();
    }
}</pre>
</div>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data
{
    <span style="color: #008000;">/// &lt;summary&gt;</span>
    <span style="color: #008000;">/// 戸当りマスタ登録・変更画面の概要説明です。</span>
    <span style="color: #008000;">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">RoomTypeList1</span>
    {
        <span style="color: #0000ff;">public</span> RoomTypeList1()
        {
            CreateDataForDemo();
        }

        <span style="color: #0000ff;">public</span> RoomTypeList1(<span style="color: #2b91af;">string</span> houseNumber)
        {
            CreateDataForDemo2(houseNumber);
        }

        [Excel("部屋数1")]
        <span style="color: #0000ff;">public</span> <span style="color: #2b91af;">string</span> HouseNumber=<span style="color: #a31515;">"12"</span>;

        <strong>[ExcelRange("CHILDLIST1")]</strong>
        <span style="color: #0000ff;">public</span> IList&lt;RowRangeServiceData1&gt; MasterDoorChildList = <span style="color: #0000ff;">new</span> List&lt;RowRangeServiceData1&gt;();
    }
}</pre>
</div>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;
<span style="color: #0000ff;">using</span> System.Configuration;
<span style="color: #0000ff;">using</span> System.IO;
<span style="color: #0000ff;">using</span> System.Reflection;

<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Handler;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Data;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Config;

<span style="color: #0000ff;">using</span> OpenXmlDemoData.DataProvider;
<span style="color: #0000ff;">using</span> OpenXmlDemoData.Data;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData
{
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">DataService</span>
    {

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Assign a data provider manager or data range provider to a template for specified template id</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;param name="handler"&gt;&lt;/param&gt;</span>
        <span style="color: #008000;">/// &lt;param name="sheetIndex"&gt;&lt;/param&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> GetDocumentData(IOpenXmlHandler handler, <span style="color: #2b91af;">int</span> sheetIndex)
        {
            <span style="color: #0000ff;">switch</span> (handler.TemplateId)
            {
                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"RowRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            <span style="color: #008000;">// you can get from web service etc., for simple, here just new a data model </span>
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                            <span style="color: #0000ff;">new</span> RowRangeServiceData1());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;

                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"RowListRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> RowListRangeServiceData());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;

                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"ComplexRowCloneRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> ComplexRowCloneRangeServiceData());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;
            }
        }</pre>
</div>
<p><strong>3.6.5. <a name="3.6.5">How to create your class of IRangeDataProvider </a></strong><br />
If you need to search data from database, web service or other services in background, you might want to create your own implementation class of IRangeDataProvider. If your searched result is designed as data model demonstrated in the example above, the most convenient way is to create a sub class of DataModelRangeDataProvider. DataModelRangeDataProvider performs interface methods of IRangeDataProvider, but ReadRangeData() and WriteRangeData() do nothing. You can override these two methods in your way. When you open or parse document, firstly, IDataProviderManager calls ReadRangeData() to get data, then IDataProviderManager parses gotten data. When you save edited document by calling ExcelHandler or OpenXmlHandler&#8217;s Save() method, firstly, the Save() method will call Flush() method to save edited data into mapped data model of RangeData then call WriteRangeData() to save RangeData to database or other services.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;
<span style="color: #0000ff;">using</span> System.IO;
<span style="color: #0000ff;">using</span> System.Reflection;

<span style="color: #0000ff;">using</span> JanaBiz.Common.Serialize;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Data;
<span style="color: #0000ff;">using</span> OpenXmlDemoData.Data.Boat;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.DataProvider
{
    <span style="color: #008000;">/// &lt;summary&gt;</span>
    <span style="color: #008000;">/// </span>
    <span style="color: #008000;">/// This is demo for getting data from database or background service.</span>
    <span style="color: #008000;">/// Here we get data from xml resource file.</span>
    <span style="color: #008000;">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">ColumnDataProvider</span> : DataModelRangeDataProvider
    {

        <span style="color: #0000ff;">public</span> ColumnDataProvider()
            : <span style="color: #0000ff;">base</span>()
        {
        }

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Here you can call database service, web service of other background service to </span>
        <span style="color: #008000;">/// read data, the last step is assign the result data to RangeData.</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">override</span> <span style="color: #0000ff;">void</span> ReadRangeData()
        {
            <span style="color: #008000;">//here, read from xml file</span>
            Assembly assembly = Assembly.GetExecutingAssembly();
            <span style="color: #2b91af;">string</span> assemblyNamespace = assembly.FullName.Split(<span style="color: #0000ff;">new</span> <span style="color: #2b91af;">char</span>[]{<span style="color: #a31515;">','</span>})[0];
            <span style="color: #2b91af;">string</span> xmlfile = assemblyNamespace + <span style="color: #a31515;">".Resources.ColumnRangeTestData.xml"</span>;
            Stream stream = assembly.GetManifestResourceStream(xmlfile);
            BoatRace boatRace = Serializer.ReadModel&lt;BoatRace&gt;(stream);

            <span style="color: #008000;">//this must be done </span>
            <span style="color: #0000ff;">this</span>.RangeData = boatRace;
        }

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// You can write your saving data in your way.</span>
        <span style="color: #008000;">/// Here we just write the data into a xml file </span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;returns&gt;return true, if saved data successfully, otherwise false&lt;/returns&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">override</span> <span style="color: #2b91af;">bool</span> WriteRangeData()
        {
            Serializer.WriteToXml(<span style="color: #0000ff;">this</span>.RangeData, <span style="color: #a31515;">"c:\\ColumnListRangeTestData.xml"</span>);
            <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span>;
        }

    }
}</pre>
</div>
<p>In the example on the above, for simply demo, ColumnDataProvider just get data from a serialized xml resource file and write edited data into xml resource file. Next code is show how to assign the data provider to IDataProviderManager.<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Assign a data provider manager or data range provider to a template for specified template id</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;param name="handler"&gt;&lt;/param&gt;</span>
        <span style="color: #008000;">/// &lt;param name="sheetIndex"&gt;&lt;/param&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> GetDocumentData(IOpenXmlHandler handler, <span style="color: #2b91af;">int</span> sheetIndex)
        {
            <span style="color: #0000ff;">switch</span> (handler.TemplateId)
            {
                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"RowRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            <span style="color: #008000;">// you can get from web service etc., for simple, here just new a data model </span>
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                            <span style="color: #0000ff;">new</span> RowRangeServiceData1());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;

<strong>                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"ColumnListRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> ColumnDataProvider());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;
                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"ColumnCloneRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> ColumnDataProvider());
                            <span style="color: #0000ff;">break</span>;
                        <span style="color: #0000ff;">case</span> 1:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> ColumnDataProvider());
                            <span style="color: #0000ff;">break</span>;

                    }
                    <span style="color: #0000ff;">break</span>;
                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"ComplexColumnCloneRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> ComplexColumnDataProvider());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;

                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"ComplexColumnListRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> ComplexColumnDataProvider());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;
</strong>            }
        }</pre>
</div>
<p><strong>3.6.6. <a name="3.6.6">Use Metadata without template range configuration</a></strong><br />
If you don&#8217;t want to create template configuration file, you can write necessary information into ExcelRange metadata as the following.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;
<span style="color: #0000ff;">using</span> JanaBiz.Common.Serialize;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data.Boat
{
    [Serializable]
    <strong>[ExcelRange("ROOT", "B5", "EQ10", "RowRangeService")]</strong>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">BoatRace</span>
    {
        <span style="color: #0000ff;">public</span> BoatRace()
        {
        }

        <strong>[ExcelRange("HEADER", "CX4", "DF48", "BlockRangeService")]</strong>
        <span style="color: #0000ff;">public</span> BoatRaceHeader HeaderData = <span style="color: #0000ff;">new</span> BoatRaceHeader();

        <strong>[ExcelRange("LIST", "BZ4", "CK48", "ColumnListRangeServiceRL")]</strong>
        <span style="color: #0000ff;">public</span> SerializableList&lt;BoatRaceRecord&gt; itemDataList =
           <span style="color: #0000ff;">new</span> SerializableList&lt;BoatRaceRecord&gt;();

        <strong>[ExcelRange("RESULT", "H4", "Q48", "BlockRangeService")]</strong>
        <span style="color: #0000ff;">public</span> BoatRaceResult ResultData = <span style="color: #0000ff;">new</span> BoatRaceResult();
    }
}</pre>
</div>
<p>Then  set parameter of method ParseTemplate(params bool[] usingConfig) to false,  handler.ParseTemplate(false);</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;

<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Handler;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Config;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Data;
<span style="color: #0000ff;">using</span> OpenXmlDemoData;

<span style="color: #0000ff;">namespace</span> TemplateConvertDemo
{
    <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">Program</span>
    {
        <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> Main(<span style="color: #2b91af;">string</span>[] args)
        {
            <span style="color: #008000;">//create your handler </span>
            IOpenXmlHandler handler = <span style="color: #0000ff;">new</span> OpenXmlHandler();

            <span style="color: #008000;">//tell ExcelTDF which ITemplateService is used to </span>
            <span style="color: #008000;">//get template file and template range configuration</span>
            handler.GetTemplateService&lt;LocalTemplateService&gt;();

            <span style="color: #008000;">//tell ExcelTDF which IDataProviderManager and </span>
            <span style="color: #008000;">//what data model is used to data              </span>
            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                <span style="color: #0000ff;">new</span> OpenXmlDemoData.Data.RowRangeServiceData1());

            <span style="color: #008000;">//set template id to identify which template is used</span>
            handler.TemplateId = <span style="color: #a31515;">"RowRangeServiceTest"</span>;

            <span style="color: #008000;">//parse your template </span>
            <strong>handler.ParseTemplate(<span style="color: #0000ff;">false</span>);</strong>

            <span style="color: #008000;">//parse your data </span>
            handler.ParseWorkbook(<span style="color: #0000ff;">null</span>);

            <span style="color: #008000;">//get parsed document</span>
            <span style="color: #2b91af;">byte</span>[] doc = handler.GetParsedDocument();

            <span style="color: #008000;">//release some resource</span>
            handler.Close();
        }
    }
}</pre>
</div>
<p><strong>4. <a name="4">Service</a></strong></p>
<p>ExcelTDF provides many range service to process template range as what you want to. Range service are the implementation class of IExcelRangeService and set in template range configuration file. Simultaneously ExcelTDF provides some custom cell services and function services. As explained on the chapter of Custom service variable, cell services and function services has the writing format as the same as Excel formula. Custom cell services are used to perform special processing like barcode, page break and so on, there are no result returned. Function service does some special processing and returns function result as string. Simply, range service is used to process template range, custom service is used to process template cells.</p>
<p><strong>4.1. <a name="4.1">IExcelRangeService</a></strong><br />
Default range service is configured in Spring.NET objects file included in ExcelTDF package as resource file. Service name which is called ServiceId in template range is object id that is upper case and lower case sensitive.<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">&lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"RowRangeService"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.Service.RowRangeService, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>/&gt;</pre>
</div>
<p>OpenXmlContext class provides some static methods to get ids of different services. You can get all range service ids by<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">OpenXmlContext.GetRangeServiceIds();</pre>
</div>
<p>ExcelTDF full versions provides following range services.<br />
<strong> </strong><br />
	<strong><a href="#4.1.1"> . RowRangeService</a></strong><br />
	<strong><a href="#4.1.2"> . RowListRangeService</a></strong><br />
	<strong><a href="#4.1.3"> . RowCloneRangeService</a></strong><br />
	<strong><a href="#4.1.4"> . ComplexRowListRangeService</a></strong><br />
	<strong><a href="#4.1.5"> . ComplexRowCloneRangeService</a></strong><br />
	<strong><a href="#4.1.6"> . BlockRangeService</a></strong><br />
	<strong><a href="#4.1.7"> . BlockRowListRangeService</a></strong><br />
	<strong><a href="#4.1.8"> . ComplexBlockRowListRangeService</a> </strong><br />
	<strong><a href="#4.1.9"> . ColumnListRangeService</a></strong><br />
	<strong><a href="#4.1.10"> . ColumnListRangeServiceRL</a></strong><br />
	<strong><a href="#4.1.11"> . ColumnCloneRangeService</a></strong><br />
	<strong><a href="#4.1.12"> . ColumnCloneRangeServiceRL</a></strong><br />
	<strong><a href="#4.1.13"> . ComplexColumnListRangeService</a></strong><br />
	<strong><a href="#4.1.14"> . ComplexColumnListRangeServiceRL</a></strong><br />
	<strong><a href="#4.1.15"> . ComplexColumnCloneRangeService</a></strong><br />
	<strong><a href="#4.1.16"> . ComplexColumnCloneRangeServiceRL</a></strong><br />
	<strong><a href="#4.1.17"> . MultiplePageRangeService</a></strong><br />
	<strong><a href="#4.1.18"> . BlockRowCloneRangeService</a></strong><br />
	<strong><a href="#4.1.19"> . BlockColumnCloneRangeService</a></strong><br />
<strong> </strong></p>
<p><strong>4.1.1. <a name="4.1.1">RowRangeService</a></strong><br />
RowRangeService is the simplest service whose range is specified by top row index and bottom row index. RowRangeService replaces the variables in template range with data value in RangeData of IRangeDataProvider. If you specify range by cell name of LeftTop and RightBottom, the variables outside the specified column will not be processed.<br />
The template range specified with this service is able to have child ranges. Generally, the worksheet&#8217;s root range is usually specified by this service.</p>
<p><strong>4.1.2. <a name="4.1.2">RowListRangeService</a></strong><br />
RowListRangeService is used to show a data list whose first element is specified by top row index and bottom row index. RowListRangeService requires you design well-formatted rows for all element in list. The template variable between top row and bottom row will be repeatedly processed until the last element of list. If you specify range by cell name of LeftTop and RightBottom, the variables outside the specified column will not be processed. The range specified service as RowListRangeService can not have child ranges (ExcelTDF not process any child ranges even child range is specified in template range configuration file). see <a href="#4.1.4">ComplexRowListRangeService</a><br />
In template, one element of list maybe have several excel rows as a logical unit. For example, if you specified template range from top row 8 to  bottom row 10, your logical unit is (10-8+1)=3 rows. Assume your data list size is 5, all data will be outputted from row 8 to row 8+3*5-1=22.  If you specify the StartIndex and PageSize in template range configuration, the elements from StartIndex to StartIndex+PageSize will be outputted. If StartIndex + PageSize is greater than the size of list, service outputs to the last element of list. The format of all output logical rows must be the same as the first element rows except that the template variable is only written in the first element rows. The best way is that you copy all cells in the first element several times until your list&#8217;s max size. Make sure cells exist in worksheet. At sometime the cell without text (blank cell ) might not be created in worksheet by Open XML even the cells is shown. See the following diagram of RowListRangeService example.  In template range configuration first element is defined from row index is from 8 to 10. list has max size 5.</p>
<p><a href="/wp-content/uploads/2010/09/t-rowlistservice2.png"><img class="aligncenter size-large wp-image-365" title="t-rowlistservice" src="/wp-content/uploads/2010/09/t-rowlistservice2-1024x516.png" alt="" width="640" height="322" /></a></p>
<p><strong>4.1.3. <a name="4.1.3">RowCloneRangeService</a></strong><br />
RowCloneRangeService is one of usually used service. RowCloneRangeService is used to show data list too. The different from RowListRangeService is RowCloneRangeService don&#8217;t have to set format for each elements except of first element rows. RowCloneRangeService clones cells in first element rows and add them in the below. This is very useful, you don&#8217;t worry about the list size and are able to design template simply.  After cloned row are added into document, the row index of other range and the cell name of formula will be changed, ExcelTDF will recalculate row index about them again. The RowCloneRangeService can not have child ranges as the same as RowListRangeService.<br />
The following is an example. At the bottom of template, there are a Excel formula of =SUM(E21:L25) and a pull down cell. After template is processed, 99 logical unit rows are cloned. The logical row size is 3, so the number of changed rows is 99*3=297. Let us see the formula in the result diagram, SUM(E21:L25) is changed to SUM(E318:L324) and the pull down cell also is moved from row 21 to row 318 too. If RowCloneRangeService is used, the row index of objects on the below of RowCloneRangeService range will be changed automatically, you don&#8217;t have to do any work to correct row index, ExcelTDF does all for you.</p>
<p><a href="/wp-content/uploads/2010/09/t-rowrangeservice2.png"><img class="aligncenter size-full wp-image-375" title="t-rowrangeservice2" src="/wp-content/uploads/2010/09/t-rowrangeservice2.png" alt="" width="823" height="417" /></a></p>
<p>The result processed by RowCloneRangeService is shown in the following.</p>
<p><a href="/wp-content/uploads/2010/09/d-rowclonerange.png"><img class="aligncenter size-full wp-image-373" title="d-rowclonerange" src="/wp-content/uploads/2010/09/d-rowclonerange.png" alt="" width="820" height="612" /></a></p>
<p><strong>4.1.4. <a name="4.1.4">ComplexRowListRangeService</a></strong><br />
ComplexRowListRangeService is a list service like RowListRangeService. The difference between ComplexRowListRangeService and RowListRangeService is that the element of ComplexRowListRangeService&#8217;s list data is able to include child ranges and child range is able to be any range type. RowListRangeService&#8217;s element is not able to include child ranges. Because ComplexRowListRangeService is also a list service, you must design the format for all elements in list as the same way as RowListRangeService. See the following template file, template range configuration and data model. The first element of ComplexRowListRangeService is from C4 to BJ22 and named as PARENTLIST1, other elements are well-designed as the same as the first element. In the element there is a RowListRangeService which is from C8 to BE10 and named as CHILDLIST1. CHILDLIST1&#8242;s maximum data size is 5 in first element of  PARENTLIST1.</p>
<p><a href="/wp-content/uploads/2010/09/t-complexrowlistrange.png"><img class="aligncenter size-full wp-image-383" title="t-complexrowlistrange" src="/wp-content/uploads/2010/09/t-complexrowlistrange.png" alt="" width="804" height="623" /></a></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span>
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span> &gt;
    <span style="color: #008000;">&lt;!-- sheet 1 --&gt;</span>
      &lt;object id=<span style="color: #a31515;">"ComplexRowListRangeServiceTest_SHEET1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
        &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ROOT"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"A1"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"CK275"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
           	&lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
           		&lt;ref object=<span style="color: #a31515;">"CRLRS_PARENTLIST1"</span>/&gt;
        	&lt;/list&gt;
        &lt;/property&gt;
      &lt;/object&gt;

       &lt;object id=<span style="color: #a31515;">"CRLRS_PARENTLIST1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
        &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"PARENTLIST1"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"C4"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BJ22"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"ComplexRowListRangeService"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
           	&lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        		&lt;ref object=<span style="color: #a31515;">"CRLRS_CHILDLIST1"</span>/&gt;
        	&lt;/list&gt;
        &lt;/property&gt;
      &lt;/object&gt;

      &lt;object id=<span style="color: #a31515;">"CRLRS_CHILDLIST1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
        &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"CHILDLIST1"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"C8"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BE10"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowListRangeService"</span>/&gt;
      &lt;/object&gt;
&lt;/objects&gt;</pre>
</div>
<p><a href="/wp-content/uploads/2010/09/d-complexrowlistrange.png"><img class="aligncenter size-full wp-image-384" title="d-complexrowlistrange" src="/wp-content/uploads/2010/09/d-complexrowlistrange.png" alt="" width="825" height="781" /></a></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;
<span style="color: #0000ff;">using</span> JanaBiz.Common.Serialize;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data
{

    [ExcelRange("ROOT")]
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">ComplexRowListRangeServiceData</span>
    {
        [ExcelRange("PARENTLIST1")]
        <span style="color: #0000ff;">public</span> SerializableList&lt;RoomTypeList1&gt; MasterDoorList1 = <span style="color: #0000ff;">new</span> SerializableList&lt;RoomTypeList1&gt;();

    }
}</pre>
</div>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data
{
    <span style="color: #008000;">/// &lt;summary&gt;</span>
    <span style="color: #008000;">/// </span>
    <span style="color: #008000;">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">RoomTypeList1</span>
    {
        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// variable</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        [Excel("部屋数1")]
        <span style="color: #0000ff;">public</span> <span style="color: #2b91af;">string</span> HouseNumber=<span style="color: #a31515;">"12"</span>;

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Child list range </span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        [ExcelRange("CHILDLIST1")]
        <span style="color: #0000ff;">public</span> IList&lt;RowRangeServiceData1&gt; MasterDoorChildList = <span style="color: #0000ff;">new</span> List&lt;RowRangeServiceData1&gt;();

    }
}</pre>
</div>
<p><strong>4.1.5. <a name="4.1.5">ComplexRowCloneRangeService</a></strong><br />
ComplexRowCloneRangeService is a list clone service like RowCloneRangeService. The difference between ComplexRowCloneRangeService and RowCloneRangeService is that the element of ComplexRowCloneRangeService&#8217;s list data is able to include child ranges and child range is able to be any range type. RowCloneRangeService&#8217;s element is not able to include child ranges. See the following template file, template range configuration and data model. Using ComplexRowCloneRangeService, your template design becomes very simple. As the same as service of RowCloneRangeService, you don&#8217;t have to copy the format for each element rows in the list. Following example is explained on the above of Template range example 3.<br />
Let&#8217;s see more detail. ComplexRowCloneRangeService processes the range named PARENTLIST1 from B5 to BJ11, which has a RowCloneRangeService range from C8 to BE10 with color of green named CHILDLIST1.</p>
<p>The cell AA11&#8242;s template variable expression is #C{S4=SUM(SHⅡ本体)}, it is  in the range of PARENTLIST1. The variable name is S4 and referenced variable is SHⅡ本体 which is in the child range of CHILDLIST1. In the first element of PARENTLIST1, the child list has 5 elements, so the variable cells of SHⅡ本体 is AA8,AA11,AA14,AA17,AA20 and the result of formula is =SUM(AA8,AA11,AA14,AA17,AA20). Please see the other variables on the template S1, S1, S2..S10,S11, their behavior are the same as S4.</p>
<p>The cell  C11 in the range of PARENTLIST1 is normal formula, you can see it is become =SUM(L23:BE23), because row index is changed. It is the sum of S1..S11.</p>
<p>See the cells of AZ15, BE15, they are the variables expression #C{=SUM(S10)} and #C{=SUM(NWS本体)}. These two variables are in the range of ROOT. See the result on the diagram and what formula they have been changed to.</p>
<p><a href="/wp-content/uploads/2010/09/t-complexrowclonerange2.png"><img class="aligncenter size-full wp-image-401" title="t-complexrowclonerange" src="/wp-content/uploads/2010/09/t-complexrowclonerange2.png" alt="" width="962" height="375" /></a></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">&lt;?xml version=<span style="color: #a31515;">"1.0"</span> encoding=<span style="color: #a31515;">"utf-8"</span>?&gt;
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span> &gt;
  &lt;!-- sheet 1 --&gt;
  &lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"ComplexRowCloneRangeServiceTest_SHEET1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"ROOT"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"Top"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"1"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"Bottom"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"18"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"RowRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;<span style="color: #0000ff;">ref</span> <span style="color: #2b91af;">object</span>=<span style="color: #a31515;">"CRCRS_PARENTLIST1"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af;">object</span>&gt;

  &lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"CRCRS_PARENTLIST1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"PARENTLIST1"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"B5"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"BJ11"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"ComplexRowCloneRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;<span style="color: #0000ff;">ref</span> <span style="color: #2b91af;">object</span>=<span style="color: #a31515;">"CRCRS_CHILDLIST1"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af;">object</span>&gt;

  &lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"CRCRS_CHILDLIST1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"CHILDLIST1"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"C8"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"BE10"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"RowCloneRangeService"</span>/&gt;
  &lt;/<span style="color: #2b91af;">object</span>&gt;

&lt;/objects&gt;</pre>
</div>
<p><a href="/wp-content/uploads/2010/09/d-complexrowclonerange.gif"><img class="alignleft size-full wp-image-397" title="d-complexrowclonerange" src="/wp-content/uploads/2010/09/d-complexrowclonerange.gif" alt="" width="960" height="720" /></a><br />
<a href="/wp-content/uploads/2010/09/d-complexrowclonerange-21.png"><img class="aligncenter size-full wp-image-405" title="d-complexrowclonerange-2" src="/wp-content/uploads/2010/09/d-complexrowclonerange-21.png" alt="" width="939" height="502" /></a></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data
{

    [ExcelRange("ROOT")]
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">ComplexRowCloneRangeServiceData</span>
    {
        <span style="color: #0000ff;">public</span> ComplexRowCloneRangeServiceData()
        {
            CreateDataForDemo();
        }

        [ExcelRange("PARENTLIST1")]
        <span style="color: #0000ff;">public</span> IList&lt;RoomTypeList1&gt; MasterDoorList1 = <span style="color: #0000ff;">new</span> List&lt;RoomTypeList1&gt;();

    }
}</pre>
</div>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data
{
    <span style="color: #008000;">/// &lt;summary&gt;</span>
    <span style="color: #008000;">/// </span>
    <span style="color: #008000;">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">RoomTypeList1</span>
    {
        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// variable</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        [Excel("部屋数1")]
        <span style="color: #0000ff;">public</span> <span style="color: #2b91af;">string</span> HouseNumber=<span style="color: #a31515;">"12"</span>;

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Child list range </span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        [ExcelRange("CHILDLIST1")]
        <span style="color: #0000ff;">public</span> IList&lt;RowRangeServiceData1&gt; MasterDoorChildList = <span style="color: #0000ff;">new</span> List&lt;RowRangeServiceData1&gt;();

    }
}</pre>
</div>
<p><strong>4.1.6. <a name="4.1.6">BlockRangeService</a></strong><br />
BlockRangeService is as the same as RowRangeService except that the range is specified by cell name. It is a service to process a rectangle region. If you only want to process some special region by service, BlockRangeService is very useful. You can split your complicated template into some simple region to process one by one. The range of RowRangeService is able to be specified by cell name too. In this case RowRangeService has the same action as BlockRangeService. About more detail see RowRangeService.</p>
<p><strong>4.1.7. <a name="4.1.7">BlockRowListRangeService</a></strong><br />
BlockRowListRangeService is the same as RowListRangeService except that the range is specified by cell name. It is also a service to process a rectangle region, but in the region, data is output as list by rows. If the range of RowListRangeService is specified by cell name, RowListRangeService has the same action as BlockRowListRangeService. About more detail, see RowListRangeService.</p>
<p><strong>4.1.8. <a name="4.1.8">ComplexBlockRowListRangeService</a></strong><br />
CpmplexBlockRowListRangeService is a list service whose range is defined by cell name and is able to have child ranges in the list elements. The behavior is like ComplexRowListRangeService. About more detail, see <a href="#4.1.4">ComplexRowListRangeService</a>.</p>
<p><strong>4.1.9-10. <a name="4.1.9">ColumnListRangeService</a> and <a name="4.1.10">ColumnListRangeServiceRL</a></strong><br />
ColumnListRangeService is similar to the RowListRangeService but the range is specified by column index. ColumnListRangeService outputs data from left to right as list. The first element is outputted on the left side of the range. In the opposite, the ColumnListRangeServiceRL outputs data from right to the left. The first element is outputted on the right side of the range. As the same as service of RowListRangeService, you must make sure all element&#8217;s columns have the same format.  See the diagram following, the gray region is processed by ColumnListRangeServiceRL.<br />
<a href="/wp-content/uploads/2010/09/t-columnlistrange.png"><img class="aligncenter size-full wp-image-417" title="t-columnlistrange" src="/wp-content/uploads/2010/09/t-columnlistrange.png" alt="" width="710" height="519" /></a></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">&lt;?xml version=<span style="color: #a31515;">"1.0"</span> encoding=<span style="color: #a31515;">"utf-8"</span>?&gt;
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span>&gt;
  &lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"ColumnListRangeServiceTest_SHEET1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"ROOT"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"B2"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"EQ50"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"RowRangeService"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;<span style="color: #0000ff;">ref</span> <span style="color: #2b91af;">object</span>=<span style="color: #a31515;">"ColumnListRangeServiceTest_1_HEADER"</span> /&gt;
        &lt;<span style="color: #0000ff;">ref</span> <span style="color: #2b91af;">object</span>=<span style="color: #a31515;">"ColumnListRangeServiceTest_1_LIST"</span> /&gt;
        &lt;<span style="color: #0000ff;">ref</span> <span style="color: #2b91af;">object</span>=<span style="color: #a31515;">"ColumnListRangeServiceTest_1_RESULT"</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af;">object</span>&gt;
  &lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"ColumnListRangeServiceTest_1_HEADER"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"HEADER"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"CX4"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"DF48"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"BlockRangeService"</span> /&gt;
  &lt;/<span style="color: #2b91af;">object</span>&gt;
  &lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"ColumnListRangeServiceTest_1_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"BZ4"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"CK48"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"ColumnListRangeServiceRL"</span> /&gt;
  &lt;/<span style="color: #2b91af;">object</span>&gt;
  &lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"ColumnListRangeServiceTest_1_RESULT"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"RESULT"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"H4"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"Q48"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"BlockRangeService"</span> /&gt;
  &lt;/<span style="color: #2b91af;">object</span>&gt;

&lt;/objects&gt;</pre>
</div>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;
<span style="color: #0000ff;">using</span> JanaBiz.Common.Serialize;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data.Boat
{
    [Serializable]
    [ExcelRange("ROOT")]
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">BoatRace</span>
    {
        <span style="color: #0000ff;">public</span> BoatRace()
        {
        }

        [ExcelRange("HEADER")]
        <span style="color: #0000ff;">public</span> BoatRaceHeader HeaderData = <span style="color: #0000ff;">new</span> BoatRaceHeader();

        [ExcelRange("LIST")]
        <span style="color: #0000ff;">public</span> SerializableList&lt;BoatRaceRecord&gt; itemDataList =
           <span style="color: #0000ff;">new</span> SerializableList&lt;BoatRaceRecord&gt;();

        [ExcelRange("RESULT")]
        <span style="color: #0000ff;">public</span> BoatRaceResult ResultData = <span style="color: #0000ff;">new</span> BoatRaceResult();
    }
}</pre>
</div>
<p><strong>4.1.11-12. <a name="4.1.11">ColumnCloneRangeService</a> and <a name="4.1.12">ColumnCloneRangeServiceRL</a></strong><br />
<a href="/wp-content/uploads/2010/09/t-columnclonerange.png"><img class="alignright size-full wp-image-420" title="t-columnclonerange" src="/wp-content/uploads/2010/09/t-columnclonerange.png" alt="" width="371" height="521" /></a><br />
ColumnCloneRangeService is similar to the RowCloneRangeService but the range is specified by column index. ColumnCloneRangeService clones specified columns and add cloned columns one by one from left to right. In the opposite, the ColumnCloneRangeServiceRL clones specified columns and add cloned columns one by one from right to left like the Japanese newspaper. Using ColumnCloneRangeService you don&#8217;t have to copy all elements format as ColumnListRangeService. After processed, column index of some ranges, formulas, objects will be recalculated and moved automatically.</p>
<p>The result is shown in the following.<br />
<a href="/wp-content/uploads/2010/09/d-columnclonerange.png"><img class="aligncenter size-full wp-image-424" title="d-columnclonerange" src="/wp-content/uploads/2010/09/d-columnclonerange.png" alt="" width="702" height="510" /></a></p>
<p><strong>4.1.13-14. <a name="4.1.13">ComplexColumnListRangeService</a> and <a name="4.1.14">ComplexColumnListRangeServiceRL</a></strong><br />
ComplexColumnListRangeService is a list service like ColumnListRangeService. The difference between ComplexColumnListRangeService and ColumnListRangeService is that the element of ComplexColumnListRangeService’s list data is able to include child ranges and child range is able to be any range type. ColumnListRangeService’s element is not able to include child ranges. Because ComplexColumnListRangeService is also a list service, you must design the format for all elements in list as the same way as ColumnListRangeService. If in the element of ComplexColumnListRangeService there is a child range using ColumnListRangeService, make sure each element’s format is designed well too. See the following template file, template range configuration and data model.</p>
<p>Here ROOT range has two child ranges named TITLE and DATA. TITLE is a BlockRangeService and has one child range SIMAI which is processed by service BlockRowListRangeService. Let us see DATA range in detail. DATA range is processed by ComplexColumnListRangeService which has four child ranges; those of them are processed by BlockRowListRangeService. To understand how it works, please check the each child range&#8217;s region. ComplexColumnListRangeService adds the data from left to right. In the contrary, ComplexColumnListRangeServiceRL processes the data from right to left.</p>
<p>The following is the part of template.</p>
<p><a href="/wp-content/uploads/2010/09/t-complexcolumnlistrange2.png"><img class="aligncenter size-full wp-image-431" title="t-complexcolumnlistrange" src="/wp-content/uploads/2010/09/t-complexcolumnlistrange2.png" alt="" width="749" height="817" /></a></p>
<p>Here is the template range configuration file.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span>
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span>&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_SHEET1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ROOT"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"A1"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"IR147"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_ROOT_TITLE"</span> /&gt;
        &lt;ref object=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_ROOT_DATA"</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_ROOT_TITLE"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"TITLE"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B2"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"K147"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRangeService"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_TITLE_SIMAI"</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_TITLE_SIMAI"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"SIMAI"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B32"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"B46"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_ROOT_DATA"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"DATA"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L2"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"U147"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"ComplexColumnListRangeService"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_NAME_LIST"</span> /&gt;
        &lt;ref object=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_DA_LIST"</span> /&gt;
        &lt;ref object=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_BAJYU_LIST"</span> /&gt;
        &lt;ref object=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_DA2_LIST"</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_NAME_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"NAME_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L32"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"L33"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_DA_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"DA_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L58"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"S59"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_BAJYU_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"BAJYU_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L66"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"U81"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_DA2_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"DA2_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L120"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"T121"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
&lt;/objects&gt;</pre>
</div>
<p>The result processed by ComplexColumnListRangeService is shown in the following.<br />
<a href="/wp-content/uploads/2010/09/d-complexcolumnlistrange.png"><img class="aligncenter size-full wp-image-433" title="d-complexcolumnlistrange" src="/wp-content/uploads/2010/09/d-complexcolumnlistrange.png" alt="" width="683" height="819" /></a></p>
<p><strong>4.1.15-16. <a name="4.1.15">ComplexColumnCloneRangeService</a> and <a name="4.1.16">ComplexColumnCloneRangeServiceRL</a></strong><br />
<a href="/wp-content/uploads/2010/09/t-complexcolumnclonerange.png"><img class="alignright size-full wp-image-438" title="t-complexcolumnclonerange" src="/wp-content/uploads/2010/09/t-complexcolumnclonerange.png" alt="" width="206" height="826" /></a><br />
ComplexColumnCloneRangeService is a list clone service like ColumnCloneRangeService. The difference between ComplexColumnCloneRangeService and ColumnCloneRangeService is that the element of ComplexColumnCloneRangeService’s list data is able to include child ranges and child range is able to be any range type. ColumnCloneRangeService’s element is not able to include child ranges. See the following template file, template range configuration and data model. Using ComplexColumnCloneRangeService, your template design becomes very simple. As the same as service of ColumnCloneRangeService, you don’t have to copy the format for each element rows in the list. Here we use ComplexColumnCloneRangeServiceRL to process the range of DATA, the cloned columns are added into the left of range DATA from right to left. The range of DATA has four child ranges. The child range of BAJYU_LIST has three elements; the first element region is from B66 to K81. Please check the output result. The column index of formulas and other objects in the right of range DATA will be changed, ExcelTDF automatically searches these objects and changes the column index of them.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span>
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span>&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnCloneRangeServiceTest_SHEET1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ROOT"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"A1"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"Q148"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"CCCRST_1_TITLE"</span> /&gt;
        &lt;ref object =<span style="color: #a31515;">"CCCRST_1_DATA"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"CCCRST_1_TITLE"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"TITLE"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L2"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"U147"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRangeService"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"CCCRST_1_SIMAI"</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"CCCRST_1_SIMAI"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"SIMAI"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L32"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"U33"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;  

  &lt;object id=<span style="color: #a31515;">"CCCRST_1_DATA"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"DATA"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B2"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"K147"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"ComplexColumnCloneRangeServiceRL"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"CCCRST_1_DA_LIST"</span> /&gt;
        &lt;ref object=<span style="color: #a31515;">"CCCRST_1_BAJYU_LIST"</span> /&gt;
        &lt;ref object=<span style="color: #a31515;">"CCCRST_1_DA2_LIST"</span> /&gt;
        &lt;ref object=<span style="color: #a31515;">"CCCRST_1_NAME_LIST"</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"CCCRST_1_DA_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"DA_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"C58"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"I59"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"CCCRST_1_BAJYU_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"BAJYU_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B66"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"K81"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"CCCRST_1_DA2_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"DA2_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B120"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"K121"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"CCCRST_1_NAME_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"NAME_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B32"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"K33"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"CCCRST_SHEET2"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ROOT"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"A1"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BP41"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"CCCRST_SHEET3"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ROOT"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"A1"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BP41"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span> /&gt;
  &lt;/object&gt;
&lt;/objects&gt;</pre>
</div>
<p>Following is the result document processed by ComplexCiolumnCloneRangeService.</p>
<p><a href="/wp-content/uploads/2010/09/d-complexcolumnclonerange.png"><img class="aligncenter size-full wp-image-446" title="d-complexcolumnclonerange" src="/wp-content/uploads/2010/09/d-complexcolumnclonerange.png" alt="" width="732" height="821" /></a></p>
<p><strong>4.1.17. <a name="4.1.17">MultiplePageRangeService</a></strong><br />
MultiplePageRangeService is created to process some complicated reports or excel documents which has multiple different page designs. Sometimes we want to create a report which has page header, page footer, report header and report footer. In ExcelTDF, you can considered them as some ranges. In fact, using RowRangeService or BlockRowRangeService, you can output header and footer information easily. If your document or report has only one page, you can do your design using services explained on the above. By assembling those services, ExcelTDF is able to output various documents and reports as what you want. If your report has more pages that all of them are the same design, you can use ComplexRowCloneRangeService or ComplexRowListRangeService to output your report page by page.  In this case, a page is an element of list. MultiplePageRangeService provides ability for creating document and report which has different page design while a list data might be outputted across all pages. Usually we want to output some summary information into the first page or last page, the detail information page by page. Depending on the size of list data, the number of pages to be outputted will be variable. MultiplePageRangeService controls these behaviors according to the properties set in the template range configuration file. MultiplePageRangeService is able to process document and report which has two or three different page designs.</p>
<p>Let us see following template, which has two reports, owner sales report and parking sales report. In the template, owner sales report has three different pages and parking sales report has one page. We want to output owner report and parking report for one owner in one worksheet. One owner maybe has a lot of parking, we need to output parking name, parking sales amount as one line for each parking in the owner report and output parking sales amount detail data in the parking report.</p>
<p>Download template <a href="/wp-content/uploads/2010/09/SalesReport1.xlsx">SalesReport</a></p>
<p><a href="/wp-content/uploads/2010/09/t-multitemplatepagerange.png"><img class="aligncenter size-full wp-image-455" title="t-multitemplatepagerange" src="/wp-content/uploads/2010/09/t-multitemplatepagerange.png" alt="" width="1236" height="608" /></a></p>
<p>Parking sales report template page is omitted.</p>
<p>The following is template range configuration file, download <a href="/wp-content/uploads/2010/09/SalesReport.zip">SalesReport</a><br />
In the worksheet, there are two child ranges, and they are owner report and parking report named OWNER_REPORT, PARKING_REPORT. Owner report range has three page child ranges, OWNER_PAGE1, OWNER_PAGE2, OWNER_PAGE3. For three page ranges, there is a list range of sales amount for each parking.  Assume the owner has 56 parkings, the list size will be 56. In the template configuration, the PageSize of the range PARK_DATA_LIST in OWNER_PAGE1, OWNER_PAGE2, OWNER_PAGE3 is 15, so the owner report will be output 4 pages. The property of IsRepeat in internal page OWNER_PAGE2, which is set to true, means this page is able to output repeated. ExcelTDF controls output behavior based on those properties. PARK_DATA_LIST range is outputted across all pages, this behavior is controlled by property of IsCrosssPage.  Besides owner report, each parking detail data is outputed as one page, thus in the worksheet we output owner report as 4 pages and parking report as 56 pages.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">&lt;?xml version="1.0" encoding="utf-8" ?&gt;</span>
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span> &gt;
  <span style="color: #008000;">&lt;!-- sheet 1 --&gt;</span>
  &lt;object id=<span style="color: #a31515;">"SalesReport_SHEET1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"SALES_REPORT"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B1"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BG209"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"OwnerReport"</span>/&gt;
        &lt;ref object=<span style="color: #a31515;">"ParkReport"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"OwnerReport"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"OWNER_REPORT"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B1"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BG150"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"MultiplePageRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"OwnerPage1"</span>/&gt;
        &lt;ref object=<span style="color: #a31515;">"OwnerPage2"</span>/&gt;
        &lt;ref object=<span style="color: #a31515;">"OwnerPage3"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"OwnerPage1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"OWNER_PAGE1"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span>   value=<span style="color: #a31515;">"B1"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BG50"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span>   value=<span style="color: #a31515;">"RowRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"ParkData1"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"ParkData1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"PARK_DATA_LIST"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B24"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BG24"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowListRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"PageSize"</span> value=<span style="color: #a31515;">"15"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"IsCrossPage"</span> value=<span style="color: #a31515;">"true"</span>/&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"OwnerPage2"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span>   value=<span style="color: #a31515;">"OWNER_PAGE2"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span>     value=<span style="color: #a31515;">"B51"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"AT100"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span>   value=<span style="color: #a31515;">"ComplexRowCloneRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"IsRepeat"</span>    value=<span style="color: #a31515;">"true"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"ParkData2"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"ParkData2"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"PARK_DATA_LIST"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B74"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"AJ74"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowListRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"PageSize"</span> value=<span style="color: #a31515;">"15"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"IsCrossPage"</span> value=<span style="color: #a31515;">"true"</span>/&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"OwnerPage3"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span>   value=<span style="color: #a31515;">"OWNER_PAGE3"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span>     value=<span style="color: #a31515;">"B101"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"AT150"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span>   value=<span style="color: #a31515;">"RowRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"ParkData3"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"ParkData3"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"PARK_DATA_LIST"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B124"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"AJ124"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowListRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"PageSize"</span> value=<span style="color: #a31515;">"15"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"IsCrossPage"</span> value=<span style="color: #a31515;">"true"</span>/&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"ParkReport"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"PARK_REPORT"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B151"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"AT209"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"ComplexRowCloneRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"AdditionItems"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"AdditionItems"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ADDITIONS"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B192"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"AJ192"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span>/&gt;
  &lt;/object&gt;

&lt;/objects&gt;</pre>
</div>
<p>Download the result of report  <a href="/wp-content/uploads/2010/09/SalesReport2.xlsx">SalesReport result</a></p>
<p>The following is a part of data model.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using JanaBiz.OpenXml;

namespace OpenXmlDemoData.Data
{
    /// &lt;summary&gt;
    /// sales report
    /// &lt;/summary&gt;
    [ExcelRange("SALES_REPORT")]
    public class SalesReportData
    {
        #region constructor

        public SalesReportData()
        {
        }

        #endregion

        /// &lt;summary&gt;
        /// all parking data of owner
        /// &lt;/summary&gt;
        [ExcelRange("OWNER_REPORT")]
        public OwnerSalesReport ownerReport = new OwnerSalesReport();

        /// &lt;summary&gt;
        /// sales data of parking
        /// &lt;/summary&gt;
        [ExcelRange("PARK_REPORT")]
        public IList&lt;OwnerParkSalesData&gt; ParkList
        {
            get { return ownerReport.ParkList; }
        }
    }
}</pre>
</div>
<p><strong>4.1.18. <a name="4.1.18">BlockRowCloneRangeService</a></strong><br />
BlockRowCloneRangeService is similar to the RowCloneRangeService. The difference is that BlockRowCloneRangeService clones only cells from specified top row to bottom row between specified columns, so the row index of cells that is between the specified columns and row index is greater than the bottom row will be moved after cloned rows are added.<br />
On the other hand, the RowCloneRangeService clones cells from specified top row to bottom row without the limitation of column and moves all cell&#8217;s index below the range itself after the cloned rows are added.</p>
<p><a href="/wp-content/uploads/2010/09/t-blockrowclonerange.png"><img class="aligncenter size-full wp-image-597" title="t-blockrowclonerange" src="/wp-content/uploads/2010/09/t-blockrowclonerange.png" alt="" width="684" height="558" /></a></p>
<p>The result is shown in the following, you can see the range B3 and K4 is cloned and added on the below. The cells that the column index is between column B and K and the row is greater than 4 are moved.</p>
<p><a href="/wp-content/uploads/2010/09/d-blockrowclonerange.png"><img class="aligncenter size-full wp-image-598" title="d-blockrowclonerange" src="/wp-content/uploads/2010/09/d-blockrowclonerange.png" alt="" width="692" height="601" /></a></p>
<p><strong>4.1.19. <a name="4.1.19">BlockColumnCloneRangeService</a></strong><br />
BlockColumnCloneRangeService is similar to the ColumnCloneRangeService. The difference is that BlockColumnCloneRangeService clones only cells from specified left column to right column between specified rows, so the column index of cells that is between the specified rows and greater than the right column will be moved after cloned columns are added.<br />
On the other hand, the ColumnCloneRangeService clones columns from specified left column to right column without row limitation, the columns index that is greater than the right column will be changed after cloned columns is added.</p>
<p><a href="/wp-content/uploads/2010/09/t-blockcolumnclonerange.png"><img class="aligncenter size-full wp-image-601" title="t-blockcolumnclonerange" src="/wp-content/uploads/2010/09/t-blockcolumnclonerange.png" alt="" width="780" height="524" /></a></p>
<p>The result is shown in the following, you can see the range B3 and C23 is cloned and added on the right. The cells that row is  between row 3 and 23 and column is greater than C are moved.</p>
<p><a href="/wp-content/uploads/2010/09/d-blockcolumnclonerange.png"><img class="aligncenter size-full wp-image-603" title="d-blockcolumnclonerange" src="/wp-content/uploads/2010/09/d-blockcolumnclonerange.png" alt="" width="898" height="517" /></a></p>
<p><strong>4.2. <a name="4.2">IExcelCellService &amp; IExcelFunctionService</a></strong><br />
In ExcelTDF, one of the most flexible functionality is that you can create your own custom service. Custom service lets you control your cell output in the template design, that is similar to the excel function. Custom service has two types. The implementation class of IExcelCellService is custom cell service while the implementation class of IExcelFunctionService is custom function service. Cell service has no return result, in the contrary, function service return a string as result. In the custom service, the parameter can be template variable, cell name, constant of text or number. The base class of ExcelCellServiceBase provides a lot of methods to get parameter&#8217;s cell name or values. On the above example of MultiplePageRangeService, we used  XSCHECKBOX, XSPAGEBREAK, XSBARCODE cell services and XFPRANGE and XFSRANGE function services. If parameter of service is cell name, the index of cell&#8217;s row and column will be recalculated. If the parameter of service is template variable, then ExcelTDF will search template variable&#8217;s cell name.<br />
ExcelTDF provides following cell services and function services now.</p>
<p><strong>4.2.1. <a name="4.2.1">Cell Service</a></strong></p>
<p><strong>4.2.1.1. <a name="4.2.1.1">XSCHAR</a></strong><br />
Output amount digit by digit.</p>
<p>Format:<br />
%{=XSCHAR(TEXT, 1|LEFT|left|0|RIGHT|right)}<br />
%{=XSCHAR(TEXT, 1|LEFT|left|0|RIGHT|right, LEADING)}<br />
%{=XSCHAR(TEXT, 1|LEFT|left|0|RIGHT|right, LEADING, TAILING)}<br />
where TEXT is a template variable or cell name or constant of number. Second parameter of 1|LEFT|left indicates that output digit from left to right(left alignment) start with the cell of this service. 0|RIGHT|right indicates that output digit from right to left (right alignment) start with the cell of this service. The third and fourth parameter is appended char on the beginning or ending of char, that maybe dollar marker etc.</p>
<p>Example:<br />
%{=XSCHAR(&#8220;123999&#8243;, 0, &#8220;$&#8221;)}, %{=XSCHAR(A4, 1, &#8220;$&#8221;, &#8220;-&#8221;)}</p>
<p><a href="/wp-content/uploads/2010/09/f-xschar1.png"><img class="aligncenter size-full wp-image-480" title="f-xschar" src="/wp-content/uploads/2010/09/f-xschar1.png" alt="" width="537" height="156" /></a></p>
<p><strong>4.2.1.2. <a name="4.2.1.2">XSCHECKBOX</a></strong><br />
Output a checkbox. The checkbox is not a vb control, it is just using some special font.</p>
<p>Format:<br />
%{=XSCHECKBOX(FLAG)}<br />
%{=XSCHECKBOX(FLAG,TEXT)}<br />
where FLAG is a flag to indicate checked or not, 1|true is checked, otherwise not checked. The second parameter of TEXT is a string after checkbox. Both FLAG and TEXT can be a template variable, cell name of constant string, number.</p>
<p>Example:<br />
%{=XSCHECKBOX(PARKTYPE)},  %{=XSCHECKBOX(PARKTYPE, PARKNAME)}<br />
In data model<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">[Excel("PARKTYPE")]
<span style="color: #0000ff;">public</span> <span style="color: #2b91af;">int</span> ParkType

[Excel("PARKNAME")]
<span style="color: #0000ff;">public</span> <span style="color: #2b91af;">string</span> ParkName</pre>
</div>
<p><a href="/wp-content/uploads/2010/09/f-checkbox.png"><img class="aligncenter size-full wp-image-483" title="f-checkbox" src="/wp-content/uploads/2010/09/f-checkbox.png" alt="" width="616" height="100" /></a></p>
<p><strong>4.2.1.3. <a name="4.2.1.3">XSBARCODE</a></strong><br />
XSBARCODE outputs bar code on the specified image. In order to output bar code you must add a image to template where your bar code will be output. Bar code will be output as the same size as image.</p>
<p>Format:<br />
%{=XSBARCODE(IMAGENAME, BARCODETEXT, TYPE)}<br />
%{=XSBARCODE(IMAGENAME, BARCODETEXT, TYPE, SHOW_LABEL)}<br />
IMAGENAME: the image name you have added into template<br />
BARCODETEXT: bar code string, which can be template variable, cell name or constant text, number<br />
TYPE:  bar code type<br />
SHOW_LABEL: 1 or true specify to output string of bar code text.</p>
<p>Following bar code types are supported:<br />
UCC12<br />
UPCA, UPC-A<br />
UCC13, EAN13, EAN-13<br />
Interleaved2of5<br />
Industrial2of5<br />
Standard2of5<br />
LOGMARS<br />
CODE39<br />
CODE39Extended<br />
Codabar<br />
PostNet<br />
ISBN,BOOKLAND<br />
JAN13,JAN-13<br />
UPC_SUPPLEMENTAL_2DIGIT<br />
MSI_Mod10,MSI_2Mod10,MSI_Mod11,MSI_Mod11_Mod10,Modified_Plessey<br />
UPC_SUPPLEMENTAL_5DIGIT,UPCE,UPC-E<br />
EAN8,EAN-8<br />
USD8,CODE11<br />
CODE128,CODE128A<br />
CODE128B,CODE128C<br />
ITF14,CODE93</p>
<p>Example:<br />
%{=XSBARCODE(&#8220;BCODE&#8221;, BARCODENO, &#8220;UPC-A&#8221;)}<br />
BCODE is image name that bar code image will replace it.</p>
<p><a href="/wp-content/uploads/2010/09/f-barcode1.png"><img class="aligncenter size-full wp-image-488" title="f-barcode1" src="/wp-content/uploads/2010/09/f-barcode1.png" alt="" width="621" height="121" /></a></p>
<p><a href="/wp-content/uploads/2010/09/f-barcode2.png"><img class="aligncenter size-full wp-image-489" title="f-barcode2" src="/wp-content/uploads/2010/09/f-barcode2.png" alt="" width="608" height="137" /></a></p>
<p><strong>4.2.1.4. <a name="4.2.1.4">XSPAGEBREAK</a></strong><br />
Add excel page break in the worksheet for document and report printing. XSPAGEBREAK is very useful for more page output.</p>
<p>Format:<br />
%{=XSPAGEBREAK}<br />
%{=XSPAGEBREAK(ROW|CELL|VAR)}<br />
If no parameter is specified , add page break on the row of this service written. If row or cell is specified add page break on the specified row. If template variable is specified, add page break on the row on which template variable is.</p>
<p>Example: %{=XSPAGEBREAK}<br />
On the example of service MultiplePageRangeService, XSPAGEBREAK is added in the template.<br />
XSPAGEBREAK are added on the last row in last page of owner report and parking report. Parking report is a page processed a clone service. When parking page is cloned, the page break will be added on the last row of cloned page.</p>
<p><a href="/wp-content/uploads/2010/09/f-pagebreak.png"><img class="aligncenter size-full wp-image-492" title="f-pagebreak" src="/wp-content/uploads/2010/09/f-pagebreak.png" alt="" width="453" height="673" /></a></p>
<p><strong>4.2.1.5. <a name="4.2.1.5">XSVDLIST</a></strong><br />
Set cell as pull down list. It is the same as the menu of Data/Data Input/List in the Excel.</p>
<p>Format:<br />
%{VAR=XSVDLIST(&#8220;A,B,C&#8221;|AJ12:AJ20|VARIABLE)}<br />
XSVDLIST is some different from services above. The left side variable name is the value of cell in pull down list while the parameter in expression of XSVDLIST is pull down items which is able to be a string with comma separated or cell range or variable which is in the list range. The value of VAR can be referenced by other expression and can be saved back into data model as other variables.</p>
<p>Example:<br />
%{ITEM=XSVDLIST(&#8220;iPod,iPhone,iPad&#8221;)}<br />
In data model:<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">[Excel("ITEM")]
<span style="color: #0000ff;">public</span> <span style="color: #2b91af;">string</span> Item {<span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span>;}</pre>
</div>
<p><a href="/wp-content/uploads/2010/09/f-vdlist.png"><img class="aligncenter size-full wp-image-495" title="f-vdlist" src="/wp-content/uploads/2010/09/f-vdlist.png" alt="" width="466" height="58" /></a></p>
<p><strong>4.2.2. <a name="4.2.2">Function Service</a></strong><br />
Custom function service can be used in expression of custom cell service, other custom function service and Excel formula.</p>
<p><strong>4.2.2.1. <a name="4.2.2.1">XFPRANGE</a></strong><br />
Search variable from specified parent range and return the cell name such as A12 or cell name string such as A12,A13,A14 if variable is in the list. Because that ExcelTDF search variable first from range of itself, then the child ranges, if you have the same variable name in different range, this function maybe useful, you can search variable from your specified range. Usually, in child range you can reference parent range&#8217;s variable directly by this function.</p>
<p>Format:<br />
%{=XFPRANGE(VAR)}<br />
%{=XFPRANGE(VAR, PARENT_LEVEL)}<br />
VAR: template variable to be searched<br />
PARENT_LEVEL: the number of parent hierarchy<br />
second parameter is the specified number from which parent range to search variable. For example, if the second parent is 2, search variable VAR from the parent&#8217;s parent range. If no second parameter is specified, search from parent range</p>
<p>Example:<br />
#C{=SUM(XFPRANGE(FURIKOMI, 1))}<br />
On the above MultiplePageRangeService, in the first page of owner report we want to output total sum of FURIKOMI which is across in the first page, internal page and last page. So we specified search FURIKOMI from parent range, that is OWNER_REPORT which includes all pages. FURIKOMI is a variable in a list, so SUM(XFPRANGE(FURIKOMI, 1)) is the total amount.</p>
<p><strong>4.2.2.2. <a name="4.2.2.2">XFSRANGE</a></strong><br />
Search variable from all brother ranges including itself and return the cell name such as A12 or cell name string such as A12,A13,A14 if variable is in the list.</p>
<p>Format:<br />
%{=XFSRANGE(VAR)}<br />
VAR is the variable to be searched.</p>
<p>Example:<br />
#C{小計=SUM(FURIKOMI)}<br />
#C{合計=SUM(XFSRANGE(小計))}<br />
On the above MultiplePageRangeService, in owner report, each page has a variable named 小計 which is the sum amount of parking in that page and in the last page there is a variable 合計 which is the sum of all 小計 in each page. You can download sales report result on the above to see how it works.</p>
<p><strong>4.2.2.3. <a name="4.2.2.3">XFCELL</a></strong><br />
This is a simple function to get variable&#8217;s cell name and return cell name or cell name string such as A12,A13,A14.</p>
<p>Format:<br />
%{=XFCELL(VAR)}</p>
<p>Example:<br />
%{=XFCELL(ITEM)}</p>
<p><strong>4.2.2.4. <a name="4.2.2.4">XFMATCH</a></strong><br />
XFMATCH is used to search some values from specified searching range, if matched, it returns the cell names or values.</p>
<p>Format:<br />
%{XFMATCH(SEARCH_VALUES,SEARCH_RANGE)<br />
%{XFMATCH(SEARCH_VALUES,SEARCH_RANGE, PARENT_HIERARCHY)<br />
SEARCH_VALUES:  the values to be searched. which  can be a variable, cell name such as AJ12 or AJ12:AK20, or constant string separated by comma such as &#8220;A,B,C&#8221;. This function searches value by some orders. Assume SEARCH_VALUES is specified as &#8220;A,B,C&#8221;, function will search A first, if found return the result, then B, then C.<br />
SEARCH_RANGE:  the search range which can be a variable, cell name, or any constant string.<br />
PARENT_HIERARCHY:  Specify from which template range to search, 1 is the parent, 2 is the parent&#8217;s parent template range.</p>
<p>Example:<br />
#{=CONCATENATE(XFOFFSET(XFMATCH(&#8220;◎,○,▲&#8221;, 本紙, 1), 0, 1), &#8220;=&#8221;, XFOFFSET(XFMATCH(&#8220;○,▲,△&#8221;, 本紙, 1), 0, 1), XFOFFSET(XFMATCH(&#8220;△&#8221;, 本紙, 1), 0, 1))}<br />
In the example of ColumnCloneRangeService, we used function as above to search the cell which has one of values  ◎,○,▲. You can see the function is used in Excel formula expression.</p>
<p><strong>4.2.2.5. <a name="4.2.2.5">XFOFFSET</a></strong><br />
Get cell name with the specified offset. This function is like excel formula function OFFSET.</p>
<p>Format:<br />
%{=XFOFFSET(VAR,ROW,COL,PARENT_HIERARCHY)}<br />
VAR:  variable to be searched, which is a template variable.<br />
ROW:  row offset number<br />
COL:  column offset number<br />
PARENT_HIERARCHY: Specify from which template range to search, 1 is the parent, 2 is the parent&#8217;s parent template range.</p>
<p>Example:<br />
#{=CONCATENATE(XFOFFSET(XFMATCH(&#8220;◎,○,▲&#8221;, 本紙, 1), 0, 1), &#8220;=&#8221;, XFOFFSET(XFMATCH(&#8220;○,▲,△&#8221;, 本紙, 1), 0, 1), XFOFFSET(XFMATCH(&#8220;△&#8221;, 本紙, 1), 0, 1))}</p>
<p><strong>4.3. <a name="4.3">How to create your service</a></strong><br />
ExcelTDF provides mechanism to create your own range service, cell service and function service. The three interfaces are used to let you create your service easily.  These interfaces are IExcelRangeService, IExcelCellService and IExcelFunctionService.</p>
<p><strong>4.3.1. <a name="4.3.1">How to create template range service, IExcelRangeService</a></strong><br />
See the example of MyRowRangeService which do the same works as RowRangeService.</p>
<p><strong>4.3.1.1. <a name="4.3.1.1">Create IExcelRangeService implementation class</a></strong><br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;
<span style="color: #0000ff;">using</span> log4net;
<span style="color: #0000ff;">using</span> JanaBiz.Common.Serialize;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Data;

<span style="color: #0000ff;">namespace</span> myservice
{
    <span style="color: #008000;">/// &lt;summary&gt;</span>
    <span style="color: #008000;">/// Process excel range defined by top row, and bottom row.</span>
    <span style="color: #008000;">/// Template variable are replaced by value in data model.</span>
    <span style="color: #008000;">/// This is simple range. worksheet root range is this type.</span>
    <span style="color: #008000;">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">MyRowRangeService</span> : ExcelRangeServiceBase, IExcelRangeService
    {
        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Logger</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">readonly</span> ILog logger = LogManager.GetLogger(<span style="color: #0000ff;">typeof</span>(MyRowRangeService));

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">///  constructor</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #0000ff;">public</span> MyRowRangeService()
            : <span style="color: #0000ff;">base</span>()
        {
        }

        <span style="color: #0000ff;">#region interface method</span>

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Parse specified worksheet using data provider</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;param name="sheetIndex"&gt;&lt;/param&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> Parse(<span style="color: #2b91af;">int</span> sheetIndex)
        {
            <span style="color: #008000;">//if no data, not processing </span>
            <span style="color: #0000ff;">if</span> (ExcelRange == <span style="color: #0000ff;">null</span> || ExcelRange.DataProvider == <span style="color: #0000ff;">null</span>) <span style="color: #0000ff;">return</span>;

            <span style="color: #008000;">//get data provider</span>
            IRangeDataProvider dataProvider = ExcelRange.DataProvider;

            <span style="color: #008000;">//reset mapping info</span>
            ExcelRange.DataMapping.Clear();

            <span style="color: #008000;">//get mapping info from data provider</span>
            SerializableDictionary&lt;<span style="color: #2b91af;">string</span>, ExcelAttribute&gt; dmp = dataProvider.GetMappingData(dataProvider[0]);
            ExcelRange.DataMapping.Add(dmp);

            <span style="color: #008000;">//set data values into mapped variables</span>
            SetNewCellValues(ExcelRange, dmp, ExcelRange.Top, ExcelRange.Bottom, 0, 0);

            <span style="color: #008000;">//no row or column index moved or changed</span>
            ExcelRange.ChangedRowCount = 0;

            <span style="color: #008000;">//process flag of this range</span>
            ExcelRange.Parsed = <span style="color: #0000ff;">true</span>;
        }

        <span style="color: #0000ff;">#endregion</span>

    }
}</pre>
</div>
<p><strong>4.3.1.2. <a name="4.3.1.2">Add your service object into configuration file</a></strong><br />
In your application configuration file, there is Spring.NET configuration section of object; add your object as following.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">  &lt;!-- my range service--&gt;
&lt;objects&gt;
&lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"<strong>MyRowRangeService</strong>"</span> type=<span style="color: #a31515;">"myservice.MyRowRangeService, Your_Assembly(dll)"</span>  singleton=<span style="color: #a31515;">"false"</span>/&gt;
&lt;/objects&gt;</pre>
</div>
<p><strong>4.3.1.3. <a name="4.3.1.3">Set your service into your template range configuration</a></strong></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">&lt;?xml version="1.0" encoding="shift_jis"?&gt;</span>
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span> &gt;
  <span style="color: #008000;">&lt;!-- sheet 1 --&gt;</span>
  &lt;object id=<span style="color: #a31515;">"MyRowRangeService_SHEET1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ROOT"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"Top"</span> value=<span style="color: #a31515;">"8"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"Bottom"</span> value=<span style="color: #a31515;">"10"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"MyRangeService"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"MyRangeService"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"MYRANGE"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L8"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BE10"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"<strong>MyRowRangeService</strong>"</span>/&gt;
  &lt;/object&gt;
&lt;/objects&gt;</pre>
</div>
<p>That is all, now ExcelTDF will call your service of MyRowRangeService to process specified range in your template configuration file.</p>
<p><strong>4.3.2. <a name="4.3.2">How to create your custom cell service, IExcelCellService</a></strong><br />
See the example of MyVDListCellService which performs the same work as XSVDLIST</p>
<p><strong>4.3.2.1. <a name="4.3.2.1">Create implementation class of IExcelCellService</a></strong></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Collections;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;

<span style="color: #0000ff;">using</span> DocumentFormat.OpenXml;
<span style="color: #0000ff;">using</span> DocumentFormat.OpenXml.Packaging;
<span style="color: #0000ff;">using</span> DocumentFormat.OpenXml.Spreadsheet;
<span style="color: #0000ff;">using</span> log4net;

<span style="color: #0000ff;">using</span> JanaBiz.ExcelFormulaParser;

<span style="color: #0000ff;">namespace</span> myservice
{
    <span style="color: #008000;">/// &lt;summary&gt;</span>
    <span style="color: #008000;">/// My validate list cell service </span>
    <span style="color: #008000;">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">MyVDListCellService</span> : ExcelCellServiceBase, IExcelCellService
    {
        <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">readonly</span> ILog logger = LogManager.GetLogger(<span style="color: #0000ff;">typeof</span>(MyVDListCellService));

        <span style="color: #0000ff;">public</span> MyVDListCellService()
            : <span style="color: #0000ff;">base</span>()
        {
        }

        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> Parse(<span style="color: #2b91af;">int</span> sheetIndex)
        {
            <span style="color: #008000;">//1: get parameters</span>
            Parameters = GetExpressionParameters(ExprTreeNode, sheetIndex);

            <span style="color: #008000;">//2: check exists function variable in template </span>
            <span style="color: #0000ff;">if</span> (!ExcelRange.IsMyVariable(CellData.VarName))
            {
                <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ServiceException(<span style="color: #0000ff;">this</span>, <span style="color: #a31515;">"E_NO_VDLIST_VAR"</span>, CellData.VarName);
            }

            <span style="color: #008000;">//3: check if no paramter</span>
            <span style="color: #0000ff;">if</span> (Parameters.Count == 0)
            {
                <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ServiceException(<span style="color: #0000ff;">this</span>, <span style="color: #a31515;">"E_NO_PARAM"</span>);
            }

            <span style="color: #008000;">//4: check if parameter is empty</span>
            <span style="color: #2b91af;">string</span> listValues = Parameters[0].Param;
            <span style="color: #0000ff;">if</span> (<span style="color: #2b91af;">string</span>.IsNullOrEmpty(listValues))
            {
                <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ServiceException(<span style="color: #0000ff;">this</span>, <span style="color: #a31515;">"E_EMPTY_PARAM"</span>);
            }

            <span style="color: #008000;">//5: parameter type check</span>
            <span style="color: #0000ff;">switch</span> (Parameters[0].ParamType)
            {
                <span style="color: #008000;">//if it is variable</span>
                <span style="color: #0000ff;">case</span> ParamType.VARIABLE:
                    IList&lt;<span style="color: #2b91af;">string</span>&gt; cells = GetReferencesOfVariable(listValues, sheetIndex, ExcelRange, ListIndex);
                    <span style="color: #0000ff;">if</span> (cells == <span style="color: #0000ff;">null</span> || cells.Count == 0)
                    {
                        <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ServiceException(<span style="color: #0000ff;">this</span>, <span style="color: #a31515;">"E_VAR_NOT_FOUND"</span>, listValues);
                    }
                    <span style="color: #2b91af;">string</span>[] cellrefs = OpenXmlSpreadsheet.CreateMergeCellname(WorksheetPart, cells.ToArray());
                    <span style="color: #0000ff;">if</span> (cellrefs.Length &gt; 1)
                    {
                        listValues = <span style="color: #2b91af;">string</span>.Format(<span style="color: #a31515;">"{0}:{1}"</span>, cellrefs[0], cellrefs[1]);
                    }
                    <span style="color: #0000ff;">break</span>;
                <span style="color: #008000;">//if it is cell reference</span>
                <span style="color: #0000ff;">case</span> ParamType.CELL:
                <span style="color: #008000;">//if it is text </span>
                <span style="color: #0000ff;">case</span> ParamType.TEXT:
                    <span style="color: #0000ff;">break</span>;
            }

            <span style="color: #008000;">//do your work here </span>
            <span style="color: #008000;">//set data validate list formula1            </span>
            SetCellValue(CellData.DataType, CellData.CellName, CellData.CellValue);
            OpenXmlSpreadsheet.SetDataValidateFormula1(WorksheetPart, CellData.CellName, listValues);
        }
    }
}</pre>
</div>
<p><strong>4.3.2.2. <a name="4.3.2.2">Add your service object into configuration file</a></strong><br />
In your application configuration file, there is Spring.NET configuration section of object, add your object as following.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">  &lt;!-- my cell service--&gt;
&lt;objects&gt;
&lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"<strong>MYVDLIST</strong>"</span> type=<span style="color: #a31515;">"myservice.MyVDListCellService, Your_Assembly(dll)"</span>  singleton=<span style="color: #a31515;">"false"</span>/&gt;
&lt;/objects&gt;</pre>
</div>
<p>Now you can use MYVDLIST in your template. ExcelTDF will parse template and build your cell service MYVDLIST by calling your created class.</p>
<p><a href="/wp-content/uploads/2010/09/f-myvdlist.png"><img class="aligncenter size-full wp-image-512" title="f-myvdlist" src="/wp-content/uploads/2010/09/f-myvdlist.png" alt="" width="508" height="57" /></a></p>
<p><strong>4.3.3. <a name="4.3.3"> How to create your custom function service, IExcelFunctionService</a></strong><br />
Custom function service is the same as custom cell service except that function service must return a result. The result is set in property of FunctionResultValue. See the following example; it does the same work as the XFCELL function explained above.</p>
<p><strong>4.3.3.1. <a name="4.3.3.1"> Create your implementation class of IExcelFunctionService</a></strong></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Collections;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;

<span style="color: #0000ff;">using</span> log4net;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;

<span style="color: #0000ff;">namespace</span> myservice
{
    <span style="color: #008000;">/// &lt;summary&gt;</span>
    <span style="color: #008000;">/// Get variable's cell name </span>
    <span style="color: #008000;">/// %{=XFCELL(VAR)}</span>
    <span style="color: #008000;">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">MyCellFunctionService</span> : ExcelCellServiceBase, IExcelFunctionService
    {
        <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">readonly</span> ILog logger = LogManager.GetLogger(<span style="color: #0000ff;">typeof</span>(MyCellFunctionService));

        <span style="color: #0000ff;">public</span> MyCellFunctionService()
            : <span style="color: #0000ff;">base</span>()
        {
        }

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// do your work here </span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;param name="sheetIndex"&gt;&lt;/param&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> Parse(<span style="color: #2b91af;">int</span> sheetIndex)
        {
            Parameters = GetExpressionParameters(ExprTreeNode, sheetIndex);

            <span style="color: #008000;">//1: no parameter check</span>
            <span style="color: #0000ff;">if</span> (Parameters.Count == 0)
                <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ServiceException(<span style="color: #0000ff;">this</span>, <span style="color: #a31515;">"E_NO_PARAM"</span>);

            <span style="color: #008000;">//2: get cellname parameter</span>
            <span style="color: #2b91af;">string</span> var1 = Parameters[0].Param;

            <span style="color: #008000;">//3: empty parameter check</span>
            <span style="color: #0000ff;">if</span> (<span style="color: #2b91af;">string</span>.IsNullOrEmpty(var1))
                <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ServiceException(<span style="color: #0000ff;">this</span>, <span style="color: #a31515;">"E_EMPTY_PARAM"</span>);

            <span style="color: #008000;">//4: parameter type</span>
            <span style="color: #0000ff;">switch</span> (Parameters[0].ParamType)
            {
                <span style="color: #008000;">//it is a variable</span>
                <span style="color: #0000ff;">case</span> ParamType.VARIABLE:
                    FunctionResultValue = GetVariableResultAsString(
                        GetReferencesOfVariable(var1, sheetIndex, ExcelRange, ListIndex));
                    <span style="color: #0000ff;">break</span>;
                <span style="color: #008000;">//it is a cell name</span>
                <span style="color: #0000ff;">case</span> ParamType.CELL:
                    FunctionResultValue = var1;
                    <span style="color: #0000ff;">break</span>;
                <span style="color: #008000;">//for others</span>
                <span style="color: #0000ff;">default</span>:
                    <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ServiceException(<span style="color: #0000ff;">this</span>, <span style="color: #a31515;">"E_NOT_CELLNAME"</span>, var1);
            }
        }
    }
}</pre>
</div>
<p><strong>4.3.3.2. <a name="4.3.3.2">Add your service object into configuration file</a></strong><br />
In your application configuration file, there is Spring.NET configuration section of object, add your object as following.<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">  &lt;!-- my function service--&gt;
&lt;objects&gt;
&lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"<strong>MYCELL</strong>"</span> type=<span style="color: #a31515;">"myservice.MyCellFunctionService, Your_Assembly(dll)"</span>  singleton=<span style="color: #a31515;">"false"</span>/&gt;
&lt;/objects&gt;</pre>
</div>
<p>Now you can use MYCELL in your template. ExcelTDF will parse template and build your cell service MYCELL by calling your created class.</p>
<p><a href="/wp-content/uploads/2010/09/f-mycell.png"><img class="aligncenter size-full wp-image-517" title="f-mycell" src="/wp-content/uploads/2010/09/f-mycell.png" alt="" width="516" height="56" /></a><!--:--><!--:zh--><strong><a href="/post/ExcelTDF#1">1. What is ExcelTDF </a></strong></p>
<p><strong><a href="/post/ExcelTDF#2">2. Introduction</a></strong></p>
<p><strong><a name="3">3. Overview</a></strong></p>
<p><strong>3.1. <a name="3.1">How to use ExcelTDF in your solution</a></strong><br />
As the following diagram shows, ExcelTDF is able to run at server-side, client-side and client-only. The interface and usage is the same wherever the ExcelTDF is running. For the both server-side and client-side, the templates of excel are managed on the server. The difference between server-side and client-side is that client-side provides auto saving functionality.<br />
<a href="/wp-content/uploads/2010/09/aspnet-diagram.png"><img class="aligncenter size-large wp-image-804" title="aspnet-diagram" src="/wp-content/uploads/2010/09/aspnet-diagram-1024x594.png" alt="" width="640" height="371" /></a><br />
<a href="/wp-content/uploads/2010/09/clientside-diagram.png"><img class="aligncenter size-large wp-image-805" title="clientside-diagram" src="/wp-content/uploads/2010/09/clientside-diagram-1024x625.png" alt="" width="640" height="390" /></a></p>
<p><strong>3.2. <a name="3.2">ExcelTDF Core classes</a></strong><br />
ExcelTDF does almost of work for you by some core classes. <strong>Excel2007TemplateParser </strong>and <strong>Excel2007DataParser </strong> are the two of these classes. But the convenient way for you is using implementation classes of <strong>IExcelHandler </strong>or <strong>IOpenXmlHandler </strong>interface named <strong>ExcelHandler</strong>, <strong>OpenXmlHandler</strong>. Excel2007TemplateParser, as the name of class, analyzes the template file and load the <strong>template range</strong> configuration file. After template is analyzed, template parser will know the mapping relationship of variables/cells and <strong>template range</strong> tree. Excel2007DataParser analyzes your data class structure and its meta data or SQL data. Metadata named <strong>ExcelRange</strong> and <strong>ExcelAttribute</strong> defines range information and Excel cell variable information. After data is analyzed, Excel2007DataParser will know the data/variable mapping relationship and get <strong>ExcelRange</strong>&#8216;s tree structure that is used to used to  determine how to process template.</p>
<p><a href="/wp-content/uploads/2010/12/ExcelTDF-diagram.png"><img class="aligncenter size-large wp-image-761" title="ExcelTDF-diagram" src="/wp-content/uploads/2010/12/ExcelTDF-diagram-1024x612.png" alt="" width="640" height="382" /></a></p>
<p>	<strong>3.3. <a name="3.3">How to get ExcelTDF work</a></strong><br />
In order to let ExcelTDF work, there are fourth steps to do, the first two steps is only needed to do one time.<br />
	<strong> . Set Configuration</strong><br />
	<strong> . Creating template file by Excel 2007 above and creating template range configuration file. If you use Metadata to define all range information, this step can be omitted</strong><br />
	<strong> . Creating IDataProvider class or Data Model class to get data</strong><br />
	<strong> . Download or open your parsed document or report</strong></p>
<p><strong>3.4. <a name="3.4">Set Configuration</a></strong><br />
When you use ExcelTDF to process template, you should tell ExcelTDF how to get template files and template range configuration files. Your template files and template range configuration files maybe saved as files in specified directory or saved in database or gotten from service.</p>
<p><strong>3.4.1. <a name="3.4.1">Manage templates by files</a></strong><br />
Your template excel file and template range configuration file can be managed on server by files. In ExcelTDF we call it repository. Typically your configuration file is named as Repository.config. It is loaded by ExcelTDF when application starting.<br />
The following is the content of Repository.config. You can add more repositories in this file.</p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%">&lt;?xml version=<span style="color: #a31515">&quot;1.0&quot;</span> encoding=<span style="color: #a31515">&quot;utf-8&quot;</span> ?&gt;
&lt;objects xmlns=<span style="color: #a31515">&quot;http://www.springframework.net&quot;</span>&gt;
  
  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;mydemo&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.Repository.FileSystemRepositoryManager, JanaBiz.OpenXml&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RepositoryName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;myrepository&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;RepositoryUri&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;../../Templates&quot;</span>/&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

&lt;/objects&gt;
</pre>
</div>
<p>On the above, the root repository directory is ../../Templates/myrepository. This is relative path to the executable dll. Certainlly, it is can be any full path. It is also be able to database connection string or others for RepositoryUri.</p>
<p>Usually you can use following two ways to load Repository.config when application starting.</p>
<p>a).  For console application or Windows form application</p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%">[assembly: RegisterRepository(&quot;your_namespace.Repository.config&quot;)]
</pre>
</div>
<p>b). For all type of application </p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%">            OpenXmlContext.RegisterRepository(<span style="color: #a31515">&quot;your_namespace.Repository.config&quot;</span>);
</pre>
</div>
<p><br/><br/></p>
<p><strong>Refresh your repository</strong><br />
If your template range configuration file is changed or you added, removed some lines in template.xml and resource.xml, you must refresh context to load new configuration information. ExcelTDF provides a method in class OpenXmlContext to reload repositories.</p>
<p><strong>3.4.2. <a name="3.4.2">Manage templates by database</a></strong><br />
If you get template file and template range configuration file from database or other stream resource, you don&#8217;t have to set repository information . The resource handler&#8217;s protocol named &#8220;memory&#8221; will load your template file, template range configuration file into context. In order to do this work, you must create a class that implements the interface <strong>ITemplateService</strong>. By following code, you can set your database template service which implements ITemplateService. This tells ExcelTDF MyDatabaseTemplateService is used to get template file and template range configuration, similar to handler.GetTemplateService(&#8220;myconfig&#8221;) which use LocalTemplateService to load template files in the repository. There are no access limitation when using database to manage templates, you can do yourself.<br />
<!-- HTML generated using hilite.me -->
<div class="div-example">
<pre style="margin: 0; line-height: 125%">ExcelHandler handler = <span style="color: #0000ff">new</span> ExcelHandler();

<span style="color: #008000">//implements ITemplateService interface</span>
MyDatabaseTemplateService service = <span style="color: #0000ff">new</span> MyTemplateService();
handler.SetTemplateServiceservice(service);

<span style="color: #008000">//or</span>
MyDatabaseTemplateService service = handler.GetTemplateServiceservice&lt;MyDatabaseTemplateService &gt;();
</pre>
</div>
<p><strong>3.4.3. <a name="3.4.3">Get templates from web service</a></strong><br />
If your templates managed on server and you use IExcelHandler on client side, you can tell ExcelTDF getting templates by web service. In this case, your web service must implement methods defined in ITemplateService but <strong>don&#8217;t need to implement the interface</strong> of ITemplateService. This feature gives you capability of managing your templates by web service very simple. Following is some code.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">ExcelHandler handler = <span style="color: #0000ff;">new</span> ExcelHandler();
...
TemplateServiceSoapClient templateService = handler.GetTemplateService&lt;TemplateServiceSoapClient&gt;();</pre>
</div>
<p><br/><br />
<strong>3.5. <a name="3.5">Template File</a></strong><br />
<strong>keywords</strong>:<br />
       <strong> . General variable</strong><br />
       <em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;${VAR1}</em><br />
       <strong> . Formula variable</strong><br />
       <em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#{=SUM(A20*SUM(VAR1)+VAR2)}</em><br />
       <strong> . Custom service variable</strong><br />
       <em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%{=XSPAGEBEAK}</em><br />
       <strong> . Parameter variable</strong><br />
       <em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;?{VAR=PARAM1}</em><br />
       <strong> . Template Range binding</strong><br />
       <em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ ExcelRange("MyRange", "A1", "Z20", "RowRangeService")]</em><br />
       <strong> . Excel Variable binding </strong><br />
       <em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Excel("VAR1"......)]</em></p>
<p><strong>3.5.1. <a name="3.5.1">Variables in Template</a></strong><br />
When template processing, IExcel2007TemplateParser will search variables in the template and collect mapped information of variable and cell name. As the result, variables are mapped into data value after Excel2007DataParser parsed document. Template variable is a name of an arbitrary text string, whose formats are defined as ${..}, #{..}, %{..}, ?{..} four types.</p>
<p><strong>3.5.1.1. <a name="3.5.1.1">General variable: ${VAR1}</a></strong><br />
VAR1 is a general variable.  ExcelTDF will replace the the variable with the value in data model or SQL query data or some others depending on what data provider is used. For the data model, here is an example.</p>
<p><a href="/wp-content/uploads/var1.png"><img src="/wp-content/uploads/var1.png" alt="" title="var1" width="203" height="65" class="aligncenter size-full wp-image-1139" /></a></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%">[ExcelRange(&quot;ROOT&quot;, &quot;A1, &quot;C3&quot;, &quot;RowRangeService&quot;)]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">MyTestMode</span>

    [Excel(&quot;VAR1&quot;)]
    <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> MyName {<span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }
}
</pre>
</div>
<p>As the above, after processed, the variable of ${VAR1} will be replaced by value of MyName property in the data mode of MyTestMode. If ${VAR1} is in list range and MyTestMode is element of list, The ${VAR1} will be the value of each element MyTestMode in the list.</p>
<p><strong>3.5.1.2. <a name="3.5.1.2">Formula variable: #{VAR2=SUM(VAR1, CJ12, 20)}</a></strong><br />
Formula variable is an Excel formula expression variable. After processed, the cell of formula variable will be a normal Excel formula function expression, such as =SUM(R12) etc. In the above expression, the left side of the equal &#8220;=&#8221; is variable name VAR2, and the right side is expression. Here VAR2&#8242;s value is the sum of VAR1. ExcelTDF will search VAR1 variable and compute the cell name of VAR1 automatically. In the expression of formula variable, you can use both normal cell name, such as  CJ12, AR12:AR20, $AR$20 and variable name. ExcelTDF is able to identify expression variable type of cell name, variable, text and number. For example, assume that VAR1 is in the list range and the cells are AK20,AK21,AK22 after range is processed, the variable of #{VAR2=SUM(VAR1, CJ12, 20)} will be explained as the sum of =SUM(AK20,AK21,AK22, CJ12, 20).<br />
<a href="/wp-content/uploads/var2.png"><img src="/wp-content/uploads/var2.png" alt="" title="var2" width="319" height="64" class="aligncenter size-full wp-image-1142" /></a></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">#{VAR2=SUM(VAR1, CJ12, 20)} --&gt; =SUM(AK20,AK21,AK22, CJ12, 20)</pre>
</div>
<div class="div-example">
<pre style="margin: 0; line-height: 125%">[ExcelRange(&quot;ROOT&quot;, &quot;A1, &quot;C3&quot;, &quot;RowRangeService&quot;)]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">MyTestMode</span>

    [Excel(&quot;VAR1&quot;)]
    <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> MyName {<span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }

    [Excel(&quot;VAR2&quot;)]
    <span style="color: #0000ff">public</span> <span style="color: #2b91af">double</span> Sum {<span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }
}
</pre>
</div>
<p>Formula variable expression is able to has sub expression. Generally no limitation on the formula expression, you can use as normal excel file. Here is complicated one. The variable&#8217;s name is MYNO, in the expression, no other variables referenced.</p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">#{MYNO=IF(ISERROR(MATCH("◎", R6:BZ6, 0))=FALSE,
    HLOOKUP("◎", R6:BZ9, 3, FALSE),
    IF(ISERROR(MATCH("○", R6:BZ6, 0))=FALSE,
          HLOOKUP("○", R6:BZ9, 3, FALSE),
          IF(ISERROR(MATCH("▲", R6:BZ6, 0))=FALSE,
                 HLOOKUP("▲", R6:BZ9, 3, FALSE),
                 IF(ISERROR(MATCH("△", R6:BZ6, 0))=FALSE,
                       HLOOKUP("△", R6:BZ9, 3, FALSE),
                       ""
                       )
                )
          )
    )}</pre>
</div>
<p>The following are also formula variables. In the expression, TRACKNO, FACTOR, QUANTITY, PRICE, BASEPRICE are referenced variables, ExcelTDF will replace them with correct cell names when building formula.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">#{VAR2=CONCATENATE("ABCD",LEFT(TRACKNO,1))}
#{VAR2=SUM(FACTOR*SUM(QUANTITY*PRICE))+ BASEPRICE*15%}</pre>
</div>
<p><strong>If no other variable references VAR2, the name of VAR2 can be omitted.</strong> for example</p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">#{=SUM(FACTOR*SUM(QUANTITY*PRICE))+ BASEPRICE*15%}</pre>
</div>
<p>Certainly, you can use excel formula directly if the cell name is not changed dynamically and don&#8217;t need to reference a variable. ExcelTDF don&#8217;t process them, for example =SUM(12*C12), <strong>this is not a variable</strong>.</p>
<p>In the excel formula variable expression, you can use custom <strong>custom function service</strong> as the same as Excel function. About <strong>custom function service</strong>, please see next section of Custom service variable.</p>
<p><strong>3.5.1.3. <a name="3.5.1.3">Custom service variable: %{VAR3=XFSRANGE(RACENO)}</a></strong><br />
Custom service variable is customized cell service or function service, which is scalable functionality  provided by ExcelTDF. ExcelTDF provides several custom cell services and function services.<br />
You can develop your custom cell service and function service too. Custom services are used to processing special cells or some computing functionality. There are two types of custom services, one is Cell Service which implements interface of IExcelCellService, and another is Function Service which implements interface of IExcelFunctionService. IExcelFunctionService is a sub interface of IExcelCellService. The two types of services are used for different purpose. In order to distinguish from Excel formula functions, cell service name and function service name in ExcelTDF start with XS and XF. In fact the name is the object id defined in the Spring.NET configuration file.</p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%">&lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;XFSRANGE&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.Service.XFSiblingRangeFunctionService, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;
</pre>
</div>
<p><br/><br />
<a href="/wp-content/uploads/var3.png"><img src="/wp-content/uploads/var3.png" alt="" title="var3" width="319" height="61" class="aligncenter size-full wp-image-1146" /></a></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%">[ExcelRange(&quot;ROOT&quot;, &quot;A1, &quot;C3&quot;, &quot;RowRangeService&quot;)]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">MyTestMode</span>

    [Excel(&quot;VAR1&quot;)]
    <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> MyName {<span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }

    [Excel(&quot;VAR2&quot;)]
    <span style="color: #0000ff">public</span> <span style="color: #2b91af">double</span> Sum {<span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }

    [Excel(&quot;VAR3&quot;)]
    <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> No {<span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }

}
</pre>
</div>
<p><br/><br />
If no other variable references VAR3, the name of VAR3 can be omitted. for example<br />
<!-- HTML generated using hilite.me -->
<div class="div-example">
<pre style="margin: 0; line-height: 125%">%{=XFSRANGE(VAR1)}
</pre>
</div>
<p><br/><br />
<strong>3.5.1.3.1. <a name="3.5.1.3.1">Cell Service</a></strong><br />
Cell service does some special processing, for example, showing a barcode.  Cell service has no result returned. Following are some cell services provided by ExcelTDF.</p>
<p>	XSBARCODE:  output a barcode<br />
	XSCHECKBOX: output a checkbox<br />
	XSPAGEBREAK: add page break of excel<br />
	XSVDLIST:   showing cell as pulldown list</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">%{=XSBARCODE("BCODE", BARCODE_NO, "UPC-A")}
%{=XSCHECKBOX(1, PLAYER)}
%{=XSPAGEBREAK(20)}
%{AAA=XSVDLIST(RESULT)}</pre>
</div>
<p>On the above, in the expression, BARCODE_NO, PLAYER, RESULT is referenced template variables.</p>
<p><strong>3.5.1.3.2. <a name="3.5.1.3.2">Function Service</a></strong><br />
Function Service does some processing and returns the result as string. Depending on what you want to do, the function&#8217;s result maybe is variable&#8217;s cell name or variable&#8217;s value. The function is able to have sub expression in which another custom function might be called. The following is a example.<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">%{=XFOFFSET(XFMATCH("◎,○,▲", RACENO, 1), 0, 1)}</pre>
</div>
<p>In the above, custom function XFMATCH is called, and the result of XFMATCH  becomes a parameter of custom function XFOFFSET.</p>
<p>Because custom function returns the result, the custom function can be called in expression of Excel formula variable expression, such as the below.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">#{=CONCATENATE(XFOFFSET(XFMATCH("◎,○,▲", RACENO, 1), 0, 1), "=", XFOFFSET(XFMATCH("○,▲,△", RACENO, 1), 0, 1), XFOFFSET(XFMATCH("△", RACENO, 1), 0, 1))}</pre>
</div>
<p>In the above, in excel formula function expression CONCATENATE, custom function XFOFFSET and XFMATCH are called.</p>
<p><em><strong>Note</strong>: Custom function service can not call excel function as sub expression because the custom function service and cell service are processed only one time while workbook are loading, not in the period of running.</em></p>
<p><strong>3.5.1.4. <a name="3.5.1.4">Parameter variable:  ?{VAR2}</a></strong><br />
Parameter variable is used to specify parameter when searching the data. This is run-time functionality like CrystalReport, in the version 1.0.0.0, no support for parameter variable.</p>
<p><strong>3.5.1.5. <a name="3.5.1.5">Data type of variable</a></strong><br />
In ExcelTDF, you can specify data type forcibly. You just need to add a special char after the leading of letter. N is number type, C is currency type, D is date type. If no N, C, D specified, the variable considered as general string type. In the version of 1.0.0.0, type N, C will forcibly set cell type as NUMBER, D is now processed as string type.  Don&#8217;t confuse the data type with data output format. Output format such as $#,###,### is set by excel on the template designing, data type just tell excel the output data is whether a number or not etc. The following is examples.</p>
<p>General variable ${VAR1}, $N{VAR1}, $C{VAR1}, $D{VAR1}<br />
${VAR1}:   output as type of string or standard<br />
$N{VAR1}: output should be a number and ExcelTDF set the cell&#8217;s type to Number<br />
$C{VAR1}: output should be currency and ExcelTDF set the cell&#8217;s type to Number<br />
$D{VAR1}: output should be date and ExcelTDF does as string or standard in the version 1.0.0.0</p>
<p>The same rules are used for formula variables, custom service variables and parameter variables.<br />
Formula variable:  #{..}, #N{..}, #C{..}, #D{..}<br />
Custom service variable:  %{..}, %N{..}, %C{..}, %D{..}<br />
Parameter variable: ?{..}, ?N{..}, ?C{..}, ?D{..}</p>
<p><strong>3.5.1.6. <a name="3.5.1.6">The Range of variable</a></strong><br />
In a range, variable must be unique, but in different range, there is no this limitation. When a variable is referenced by formula or custom service, ExcelTDF try to search the variable and find cell names or values of variable. ExcelTDF search variable by some orders. ExcelTDF always search expression variable first from the range of variable itself. If not found, ExcelTDF then search expression variable from child ranges. Last, try to search expression variable from all. Understanding the searching order will help you to get correct result.</p>
<p><strong>3.5.2. <a name="3.5.2">Template range</a></strong><br />
Template range is an excel range specified by row index or column index or excel cell name. <strong>Range Service Name</strong> must be specified to identify which template range to be processed by ExcelTDF. Template range is defined both by object in Spring.NET configuration file and by Metadata defined in data model. Defined items in template range are the properties of type of class <strong>TemplateRange</strong>.</p>
<p>When you design your template, the first thing is that you should determine how to output data with template. You can determine how many template ranges there are and how to process template ranges according to your data structure. If your data is a list, define a template range as a list service range will simplify your processing. Please see the examples to understand Template Range and Range Services.</p>
<p>Template file is a Excel workbook(*.xlsx). In this version only *.xlsx format is supported. As the known, one workbook might have several worksheets. ExcelTDF splits a worksheet as some ranges which include  some cells to be processed or not. For the cells to be processed,  the cell text might include one or more defined variables. A range might have some child ranges, and child range is able to has its own child ranges too. These range&#8217;s definition information must be specified by template range configuration file or defined by Metadata in data model. So the whole worksheet is considered as a root range, all other ranges are worksheet&#8217;s child or descendant ranges.</p>
<p>See the following diagram. The worksheet root range has three child ranges named R-A, R-E, R-D, and range R-A also has two child range R-B, R-C. From diagram we can see a tree of range.<br />
<a href="/wp-content/uploads/2010/09/template-range.png"><img class="aligncenter size-full wp-image-227" title="template-range" src="/wp-content/uploads/2010/09/template-range.png" alt="" width="824" height="456" /></a></p>
<p>The template range configuration file, simply, we can consider it as TemplateRange class. The all items&#8217; name are TemplateRange&#8217;s properties. The service name used to process range is listed in <a href="#servicenames">service names</a>, You can get all names by call OpenXmlContext&#8217;s GetRangeServiceIds() methods too.</p>
<p>The following is template whose layout is the same as description above.<br />
<a href="/wp-content/uploads/range.png"><img src="/wp-content/uploads/range.png" alt="" title="range" width="420" height="490" class="aligncenter size-full wp-image-1157" /></a></p>
<p>The following is corresponding  template range configuration file.</p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%">&lt;?xml version=<span style="color: #a31515">&quot;1.0&quot;</span> encoding=<span style="color: #a31515">&quot;utf-8&quot;</span>?&gt;
&lt;objects xmlns=<span style="color: #a31515">&quot;http://www.springframework.net&quot;</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;SAMPLE_SHEET1&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;RootRange&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;A1&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;Z51&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;RowRangeService&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ChildRanges&quot;</span>&gt;
      &lt;list element-type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span>&gt;
        &lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;R-A-ID&quot;</span> /&gt;
	&lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;R-E-ID&quot;</span> /&gt;
	&lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;R-D-ID&quot;</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;R-A-ID&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;R-A&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;B3&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;S31&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BlockRangeService&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ChildRanges&quot;</span>&gt;
      &lt;list element-type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span>&gt;
        &lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;R-B-ID&quot;</span> /&gt;
        &lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;R-C-ID&quot;</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;R-E-ID&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;R-E&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;B37&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;S49&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span>  <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BlockRangeService&quot;</span>/&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;
 
  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;R-D-ID&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;R-D&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;U2&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;Y49&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span>  <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BlockRangeService&quot;</span>/&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;R-B-ID&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;R-B&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;C9&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;Q16&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span>  <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BlockRangeService&quot;</span>/&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;R-C-ID&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;R-C&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;B20&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;Q29&quot;</span> /&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span>  <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BlockRangeService&quot;</span>/&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

&lt;/objects&gt;
</pre>
</div>
<p><br/><br />
The following is model class used to process template above.<br />
<!-- HTML generated using hilite.me -->
<div class="div-example">
<pre style="margin: 0; line-height: 125%">[ExcelRange(&quot;SHEET1&quot;)]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RT</span>
{
	[ExcelRange(&quot;R-A&quot;)]
	<span style="color: #0000ff">public</span> RA ra;
	
	[ExcelRange(&quot;R-D&quot;)]
	<span style="color: #0000ff">public</span> RD rd;

	[ExcelRange(&quot;R-E&quot;)]
	<span style="color: #0000ff">public</span> RE re;
}


<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RA</span>{

	[ExcelRange(&quot;R-B&quot;)]	
	<span style="color: #0000ff">public</span> RB rb;

	[ExcelRange(&quot;R-C&quot;)]
	<span style="color: #0000ff">public</span> RC rc
}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RB</span> {}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RC</span> {}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RD</span> {}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RE</span> {}
	
</pre>
</div>
<p><br/><br />
If you want to define range&#8217;s all information into Metadata to replace template range configuration file, the following is sample of data model.<br />
<!-- HTML generated using hilite.me -->
<div class="div-example">
<pre style="margin: 0; line-height: 125%">[ExcelRange(&quot;SHEET1&quot;, &quot;A1&quot;, &quot;Z51&quot;, &quot;RowRangeService&quot;)]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RT</span>
{
	[ExcelRange(&quot;R-A&quot;, &quot;B3&quot;, &quot;S31&quot;, &quot;BlockRangeService&quot;)]
	<span style="color: #0000ff">public</span> RA ra;
	
	[ExcelRange(&quot;R-D&quot;, &quot;U2&quot;, &quot;Y49&quot;, &quot;BlockRangeService&quot;)]
	<span style="color: #0000ff">public</span> RD rd;

	[ExcelRange(&quot;R-E&quot;, &quot;B37&quot;, &quot;Y49&quot;, &quot;BlockRangeService&quot;)]
	<span style="color: #0000ff">public</span> RE re;
}


<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RA</span>{

	[ExcelRange(&quot;R-B&quot;, &quot;C9&quot;, &quot;Q16&quot;, BlockRangeService&quot;)]	
	<span style="color: #0000ff">public</span> RB rb;

	[ExcelRange(&quot;R-C&quot;, &quot;B20&quot;, &quot;Q29&quot;, &quot;BlockRangeService&quot;)]
	<span style="color: #0000ff">public</span> RC rc
}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RB</span> {}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RC</span> {}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RD</span> {}

<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RE</span> {}
	
</pre>
</div>
<p><br/><br />
<strong>3.5.2.1. <a name="3.5.2.1">Template range example 1</a></strong><br />
Next let us see how to determine your template range by some examples.<br />
First, see the following most simple example. We just want  to replace the variables between row 8 and row 10, so the worksheet has only one root range from row 8 to row 10.</p>
<p><a href="/wp-content/uploads/template-example11.png"><img src="/wp-content/uploads/template-example11.png" alt="" title="template-example1" width="1247" height="327" class="aligncenter size-full wp-image-1164" /></a></p>
<p>In order to tell ExcelTDF the range&#8217;s information , we write these information into a Spring.NET object xml file as following.<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span>
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span> &gt;
    <span style="color: #008000;">&lt;!-- sheet 1 --&gt;</span>
      &lt;object id=<span style="color: #a31515;">"RowRangeServiceTest_sheet1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
        &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ROOT"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"Top"</span> value=<span style="color: #a31515;">"8"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"Bottom"</span> value=<span style="color: #a31515;">"10"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span>/&gt;
      &lt;/object&gt;
&lt;/objects&gt;</pre>
</div>
<p>On the above, in configuration file, the type of object is always JanaBiz.OpenXml.TemplateRange. TemplateRange has some properties must be specified. These properties are RangeName, ServiceId and range defined by (Top|Left|LeftTop) and (Bottom|Right|RightBottom). If we want to specify range by row index without column limitation, the Top and Bottom property should be set. If we want to specify range by column index without limitation of row index, the Left and Right property should be set. If we want to specify rectangle range with the limitation of row and column, the property LeftTop and RightBottom should be set.</p>
<p>	RangeName: the identifier of the range<br />
	Top/Bottom | Left/Right | LeftTop/RightBottom :  the range specified by row or column or cell name<br />
	ServiceId:  the service name used to process this range. <a href="#servicenames">see service names</a></p>
<p>The object id can be any string but it must be unique in all configuration files, For the worksheet root range, it is best to assign object id as <strong>template id + &#8220;sheet&#8221; + worksheet index </strong>. This will be convenient to ExcelTDF to find worksheet root range object. About some other property please see TemplateRange class API.</p>
<p>For the template above, following is the processed result. Because the service is RowRangeService, it just replaces the variables in specified template range with the data in data model.</p>
<p><a href="/wp-content/uploads/template-example1-result.png"><img src="/wp-content/uploads/template-example1-result.png" alt="ExcelTDF " title="template-example1-result" width="1249" height="323" class="aligncenter size-full wp-image-1166" /></a></p>
<p><strong>3.5.2.2. <a name="3.5.2.2">Template range example 2</a></strong><br />
Following is another template file. In this template file we want to output data as a list. The list&#8217;s element is from row 8 to row 10, let us see how different result will be got.</p>
<p>The template file is shown as following.</p>
<p><a href="/wp-content/uploads/template-example2.png"><img src="/wp-content/uploads/template-example2.png" alt="" title="template-example2" width="1248" height="528" class="aligncenter size-full wp-image-1168" /></a></p>
<p>The template configuration file is shown as following.</p>
<p><!-- HTML generated using hilite.me -->
<div class="div-example">
<pre style="margin: 0; line-height: 125%">&lt;?xml version=<span style="color: #a31515">&quot;1.0&quot;</span> encoding=<span style="color: #a31515">&quot;shift_jis&quot;</span>?&gt;
&lt;objects xmlns=<span style="color: #a31515">&quot;http://www.springframework.net&quot;</span> &gt;
  &lt;!-- sheet 1 --&gt;
  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;RowListRangeServiceTest_SHEET1&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;ROOT&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;Top&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;1&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;Bottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;30&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;RowRangeService&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ChildRanges&quot;</span>&gt;
      &lt;list element-type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span>&gt;
        &lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;RLRSChildList1&quot;</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;RLRSChildList1&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;CHILDLIST1&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;L8&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BN10&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;RowListRangeService&quot;</span>/&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

&lt;/objects&gt;
</pre>
</div>
<p>There are two TemplateRanges in worksheet. The worksheet root range, whose RangeName is ROOT and it has a  child range. Root range is from row 8 to row 22. Child range&#8217;s id is <strong>RLRSChildList1 </strong>and RangeName is CHILDLIST1. Child range is from L8 to BE10. Child range is processed by service of <strong>RowListRangeService </strong>which output data as list with the same format as defined range L8:BE10, Assume your list in the data model has 5 elements, the data of 5 elements will be outputted from L8 to L20.</p>
<p>The following is processed result.</p>
<p><a href="/wp-content/uploads/template-example2-result.png"><img src="/wp-content/uploads/template-example2-result.png" alt="" title="template-example2-result" width="1247" height="527" class="aligncenter size-full wp-image-1170" /></a></p>
<p>If we change the ROOT range&#8217;s row from row 7 to row 20, what will be changed? The variable of ${HouseNumber1} is in the range of ROOT, this variable will be processed. ROOT range&#8217;s ServiceId is RowRangeService, the variable is just replaced by value in data model corresponding to the ROOT range.</p>
<p><strong>3.5.2.3. <a name="3.5.2.3">Template range example 3</a></strong><br />
Next, let us see a some complicated examples. In this example we want to output a list, and the element of list is also a list. We usually bump into this case. As the shown, template design is very simple too. The outer list&#8217;s element is from B5 to BJ11, the inner list&#8217;s element is from C8 to BE10. So the variable of $N{HouseNumber1}, #C{S1=SUM(HBⅡBody)}, #C{=SUM(S10)} etc. are processed by outer list. Inner list size might be different, the service of specified will process them correctly.</p>
<p><a href="/wp-content/uploads/template-example3.png"><img src="/wp-content/uploads/template-example3.png" alt="" title="template-example3" width="1143" height="347" class="aligncenter size-full wp-image-1172" /></a></p>
<p>As the diagram of following, the worksheet has three ranges. Root range of worksheet is from row 1 to 18, which is processed by RowRangeService. The root range has a child range whose id is CRCRS_PARENTLIST1, named PARENTLIST1 and colored with gray. Child range is from B5 to BJ11, which is processed by service of <strong>ComplexRowCloneRangeService</strong>. The service named with prefix of  ComplexXX is used to process list ranges who&#8217;s element has child range. So the part of B5:BJ11 will be cloned list size-1 times. The cloned rows are inserted in the below of the last row BJ<strong>11</strong>, here it is row 12. Because the element of list includes a child range,  whose id is CRCRS_CHILDLIST1 , this range is also a cloned list, the cloned rows is from C8 to BE10, The row of parent range will be changed dynamically. ExcelTDF control ranges processing order, first parent range, then child ranges. If child range is a coned list, parent range&#8217;s row or column will be changed automatically.</p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%">&lt;?xml version=<span style="color: #a31515">&quot;1.0&quot;</span> encoding=<span style="color: #a31515">&quot;utf-8&quot;</span>?&gt;
&lt;objects xmlns=<span style="color: #a31515">&quot;http://www.springframework.net&quot;</span> &gt;
  &lt;!-- sheet 1 --&gt;
  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;ComplexRowCloneRangeServiceTest_SHEET1&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;ROOT&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;Top&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;1&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;Bottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;18&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;RowRangeService&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ChildRanges&quot;</span>&gt;
      &lt;list element-type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span>&gt;
        &lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;CRCRS_PARENTLIST1&quot;</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;CRCRS_PARENTLIST1&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;PARENTLIST1&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;B5&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BJ11&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;ComplexRowCloneRangeService&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ChildRanges&quot;</span>&gt;
      &lt;list element-type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span>&gt;
        &lt;<span style="color: #0000ff">ref</span> <span style="color: #2b91af">object</span>=<span style="color: #a31515">&quot;CRCRS_CHILDLIST1&quot;</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

  &lt;<span style="color: #2b91af">object</span> id=<span style="color: #a31515">&quot;CRCRS_CHILDLIST1&quot;</span> type=<span style="color: #a31515">&quot;JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml&quot;</span> singleton=<span style="color: #a31515">&quot;false&quot;</span>&gt;
    &lt;property name=<span style="color: #a31515">&quot;RangeName&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;CHILDLIST1&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;LeftTop&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;C8&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;RightBottom&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;BE10&quot;</span>/&gt;
    &lt;property name=<span style="color: #a31515">&quot;ServiceId&quot;</span> <span style="color: #0000ff">value</span>=<span style="color: #a31515">&quot;RowCloneRangeService&quot;</span>/&gt;
  &lt;/<span style="color: #2b91af">object</span>&gt;

&lt;/objects&gt;
</pre>
</div>
<p>The result is shown in the following. You can see, the simple template creates complicated data output. There are many patterns you can assemble by provided services in ExcelTDF.</p>
<p><a href="/wp-content/uploads/template-example3-result.png"><img src="/wp-content/uploads/template-example3-result.png" alt="" title="template-example3-result" width="1075" height="697" class="aligncenter size-full wp-image-1173" /></a></p>
<p><strong>3.5.3. <a name="3.5.3">Without template range file</a></strong><br />
If your template doesn’t need to be changed frequently, maybe you don&#8217;t want to create template range configuration file. In this case the template range information can be written in code as metadata of program. If you write range information into code, and your template layout is changed, you must modify your code. The most benefit of using template range configuration file is you don&#8217;t have to change your code if template layout changed.  For the detail, please see next chapter about data provider.</p>
<p><strong>3.6. <a name="3.6">Data Provider and Data Model</a> </strong><br />
ExcelTDF uses two types of interface to control the mapping information. IDataProviderManager controls mapping behavour of IRangeDataProvider and template range, while IRangeDataProvider controls mapping behavour of data field in data model and template variable. Data field maybe is field or property  in data model, or columns of SQL query, or some others.</p>
<p><strong>3.6.1 <a name="3.6.1">The types of data provider manager</a></strong><br />
Each implementation class of IDataProviderManager knows how to map data provider to template range. Actually manager maps RangeData in IRangeDataProvider to template range. RangeData can be data model, DataSet or other data objects. ExcelTDF provides three manager classes.</p>
<p><strong>3.6.1.1. <a name="3.6.1.1">DataModelProviderManager</a></strong><br />
DataModelProviderManager, in which the default DataModelRangeDataProvider is used,  maps data model to template range. ExcelRange and ExcelAttibute(Excel) Attribute classes are used to help ExcelTDF doing those works. The RangeData in DataModelRangeDataProvider is your data model for DataModelProviderManager. In the next you will see how to use them in data model.</p>
<p><strong>3.6.1.2. <a name="3.6.1.2">QueryProviderManager</a></strong><br />
QueryProviderManager let you create document or report by specified SQL query, all template ranges use the same one query data if you use QueryProviderManager. If you are familiar with CrystalReport, creating a query and getting report, this is the similarity functionality.</p>
<p><strong>3.6.1.3. <a name="3.6.1.3">AnyTypeProviderManager</a></strong><br />
AnyTypeProviderManager let you create document or report by any data type. You should create IRangeDataProvider for each template range. If no IRangeDataProvider found, the IRangeDataProvider of parent range will be used. You can specify a data model for a range, SQL query for another range. You can specify SQL query for each range and so on.  It is the most flexible manager.</p>
<p>See the following diagram, it shows the association between template and data.</p>
<p><a href="/wp-content/uploads/2010/09/dataprovider3.png"><img class="aligncenter size-full wp-image-300" title="dataprovider" src="/wp-content/uploads/2010/09/dataprovider3.png" alt="" width="905" height="534" /></a></p>
<p>As you see, ExcelTDF provides various IRangeDataProvider implementation classes, from data mode to usually used database, even SAP. IRangeDataProvider has two methods ReadRangeData() for getting data from database or background service, and WriteRangeData() for saving edited data to database or sending to background service. ExcelTDF maps RangeData in IRangeDataProvider to template range. ExcelTDF provides three IDataProviderManager implementation classes, they are DataModelProviderManager,  QueryProviderManager and  AnyTypeProviderManager. The three data provider managers have the different control behavior and are used in different way. The DataModelProviderManager is the most often used data provider manager. If the RangeData in IRangeDataProvider is data model, not a SQL DataSet and not SAP&#8217;s DataReader, DataModelProviderManager is your suitable selection.</p>
<p><strong>3.6.2 <a name="3.6.2">Data model of Template range example 1</a></strong><br />
In the following, let us see how to use DataModelProviderManager and what your data model should be.<br />
For the Template range example-1 which we discussed on the above, data model is shown in the diagram. Please see the fields that have defined Excel metadata, for example  [Excel("HBⅡBody")], it will map the value of HBⅡBody to the template variable defined as ${HBⅡBody}. Every template variable must have corresponding metadata with the same name in data model. If [Excel("X")] is defined in data model, but no ${X} or #{X=..} or %{X=..} found, &#8220;X&#8221; can be used in formula expression and custom service expression. For example, #{VAR2=SUM(VAR1*X/100)}, X is not a variable in template but a variable in data model. In the same way, the metadata [ExcelRange("ROOT")] tells ExcelTDF that the range information named ROOT in the template range configuration is used for this model, and variables defined in this model by metadata are mapped to template variables in the range named ROOT.</p>
<p><!-- HTML generated using hilite.me -->
<div class="div-example">
<pre style="margin: 0; line-height: 125%"><span style="color: #0000ff">using</span> System;
<span style="color: #0000ff">using</span> System.Xml.Serialization;
<span style="color: #0000ff">using</span> JanaBiz.OpenXml;

<span style="color: #0000ff">namespace</span> OpenXmlDemoData.Data
{

    [ExcelRange(&quot;ROOT&quot;)]
    [Serializable]
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">RowRangeServiceData1</span>
    {
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> HouseType;

        [Excel(&quot;HouseNumber1&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> HouseNum = <span style="color: #a31515">&quot;20&quot;</span>;

        [Excel(&quot;HBⅡBody&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">double</span> HBⅡBody;

        [Excel(&quot;VAR2&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> Var2;

        [Excel(&quot;LBⅡBody&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> LBⅡBody;

        [Excel(&quot;KCBody&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> KCBody;

        [Excel(&quot;SHⅡBody&quot;)]
        <span style="color: #0000ff">public</span> <span style="color: #2b91af">string</span> SHⅢBody;

        .....
    }
}
</pre>
</div>
<p>Here is the code to parse template and get your document. As you see, after you finished your template design and wrote well your template configuration, the coding is very simple.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;

<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Handler;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Config;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Data;
<span style="color: #0000ff;">using</span> OpenXmlDemoData;

<span style="color: #0000ff;">namespace</span> TemplateConvertDemo
{
    <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">Program</span>
    {
        <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> Main(<span style="color: #2b91af;">string</span>[] args)
        {
            <span style="color: #008000;">//create your handler </span>
            IOpenXmlHandler handler = <span style="color: #0000ff;">new</span> OpenXmlHandler();

            <span style="color: #008000;">//tell ExcelTDF which ITemplateService is used to </span>
            <span style="color: #008000;">//get template file and template range configuration</span>
            handler.GetTemplateService&lt;LocalTemplateService&gt;();

            <span style="color: #008000;">//tell ExcelTDF which IDataProviderManager and </span>
            <span style="color: #008000;">//what data model is used to data              </span>
            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                <span style="color: #0000ff;">new</span> OpenXmlDemoData.Data.RowRangeServiceData1());

            <span style="color: #008000;">//set template id to identify which template is used</span>
            handler.TemplateId = <span style="color: #a31515;">"RowRangeServiceTest"</span>;

            <span style="color: #008000;">//parse your template </span>
            handler.ParseTemplate();

            <span style="color: #008000;">//parse your data </span>
            handler.ParseWorkbook(<span style="color: #0000ff;">null</span>);

            <span style="color: #008000;">//get parsed document</span>
            <span style="color: #2b91af;">byte</span>[] doc = handler.GetParsedDocument();

            <span style="color: #008000;">//release some resource</span>
            handler.Close();
        }
    }
}</pre>
</div>
<p>In the code, creating DataModelProviderManager with parameter of RowRangeServiceData1 will enable manager use default data provider of DataModelRangeDataProvider. In fact, DataModelProviderManager have two constructors with parameter of either data model or IRangeDataProvider when you want use your customized IRangeDataProvider.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">        <span style="color: #0000ff;">public</span> DataModelProviderManager(Object dataModel)

      <span style="color: #0000ff;">public</span> DataModelProviderManager(IRangeDataProvider rootRangeDataProvider)</pre>
</div>
<p>If you want to open parsed workbook into excel in your excel AddIn program directly, ExcelHandler is prepared for you.<br />
The code is shown as the following. The step of coding is the same as the above example. Here we create and initialize handler first, and get template file and template range configuration by web service of TemplateServiceSoapClient. <strong>So your web service should perform the methods of interface ITemplateService, but your service don&#8217;t have to implement the interface of ITemplateService</strong>. This will be helpful for you to reference web service directly.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">        <span style="color: #0000ff;">private</span> ExcelHandler handler = <span style="color: #0000ff;">null</span>;
        <span style="color: #0000ff;">private</span> TemplateServiceSoapClient webService = <span style="color: #0000ff;">null</span>;

        <span style="color: #0000ff;">public</span> RibbonDemo()
        {
            InitializeComponent();
        }

        <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> RibbonDemo_Load(<span style="color: #2b91af;">object</span> sender, RibbonUIEventArgs e)
        {
            InitializeExcelHandler();
        }

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Create and initialize &lt;see cref="IExcelHandler"/&gt;</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> InitializeExcelHandler()
        {
            <span style="color: #008000;">//create IExcelHandler instance</span>
            handler = <span style="color: #0000ff;">new</span> ExcelHandler();

            <span style="color: #008000;">// set excel application </span>
            handler.ExcelApp = Globals.ThisAddIn.Application;

            <span style="color: #008000;">//create or get template service </span>
            webService = handler.GetTemplateService&lt;TemplateServiceSoapClient&gt;();

            <span style="color: #008000;">//create data service </span>
            DataService dataService = <span style="color: #0000ff;">new</span> DataService();

            <span style="color: #008000;">//get excel data event handler</span>
            handler.OnGetDocumentData += dataService.GetDocumentData;

            <span style="color: #008000;">//save excel data event handler</span>
            handler.OnSaveDocumentData += dataService.SaveDocumentData;
        }</pre>
</div>
<p>On the above, we create DataService object which performs OnGetDocumentData event handler for getting data model. Certainly you can assign DataModelProviderManager to handler directly too,  such as<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                <span style="color: #0000ff;">new</span> OpenXmlDemoData.Data.RowRangeServiceData1());</pre>
</div>
<p>Define a event handler is very flexible. First, coding logic to get data for all templates can be put in event handler method. Second, you can override IRangeDataProvider, and get data in your way. The event handler method is show in the below.<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Assign a data provider manager or data range provider to a template for specified template id</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;param name="handler"&gt;&lt;/param&gt;</span>
        <span style="color: #008000;">/// &lt;param name="sheetIndex"&gt;&lt;/param&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> GetDocumentData(IOpenXmlHandler handler, <span style="color: #2b91af;">int</span> sheetIndex)
        {
            <span style="color: #0000ff;">switch</span> (handler.TemplateId)
            {
                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"RowRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            <span style="color: #008000;">// you can get from web service etc., for simple, here just new a data model </span>
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                            <span style="color: #0000ff;">new</span> RowRangeServiceData1());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;
            }
        }</pre>
</div>
<p>Let us see the code about opening parsed document, only several lines. Open() method try to find data provider manager and data provider by event handler of OnGetDocumentData. If event handler exists, it will be called.<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Open parsed workbook of spreadsheet</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;param name="templateId"&gt;&lt;/param&gt;</span>
        <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> OpenDocument(<span style="color: #2b91af;">string</span> templateId)
        {
            <span style="color: #008000;">//close opened workbook before</span>
            handler.Close();

            <span style="color: #008000;">//template id used</span>
            handler.TemplateId = templateId;
            <span style="color: #008000;">//other input parameter for get excel data </span>
            handler.InputData = <span style="color: #0000ff;">null</span>;
            <span style="color: #008000;">//parse template</span>
            handler.ParseTemplate();
            <span style="color: #008000;">//parse workbook and open it in excel or other component</span>
            handler.Open();
        }</pre>
</div>
<p><strong>3.6.3 <a name="3.6.3">Data model of Template range example 2</a></strong><br />
In this example because the root template range has a child range, the data model is also created into two classes hierarchically. RowListRangeServiceData class has metadata [ExcelRange("ROOT")] and its field member ChildList1 has metadata [ExcelRange("CHILDLIST1")]. The names of ROOT and CHILDLIST1 matches the RangeName defined in template range configuration. In template range configuration, the ServiceId of CHILDLIST1 is RowListRangeService, so in the data model of RowListRangeServiceData, the member with metadata  [ExcelRange("CHILDLIST1")], ChildList1  must be a list.</p>
<p><em>ExcelRange binding a data model is associated to template range, and if your template range ServiceId is list related service, data member should be a list type of IList. That is all.</em></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;
<span style="color: #0000ff;">using</span> JanaBiz.Common.Serialize;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data
{
    [Serializable]
    <strong>[ExcelRange("ROOT")]</strong>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">RowListRangeServiceData</span>
    {
        <span style="color: #0000ff;">public</span> RowListRangeServiceData()
        {
            <span style="color: #008000;">//Create data for demo</span>
            <span style="color: #0000ff;">for</span> (<span style="color: #2b91af;">int</span> i = 0; i &lt; 5; i++)
            {
                ChildList1.Add(<span style="color: #0000ff;">new</span> RowRangeServiceData1());
            }
        }

       <strong>[ExcelRange("CHILDLIST1")]</strong>
        <span style="color: #0000ff;">public</span> IList&lt;RowRangeServiceData1&gt; ChildList1 = <span style="color: #0000ff;">new</span> List&lt;RowRangeServiceData1&gt;();

    }
}</pre>
</div>
<p>In OnGetDocumentData event handler we added a piece of coding for getting data model. other works are the same as example-1</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Assign a data provider manager or data range provider to a template for specified template id</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;param name="handler"&gt;&lt;/param&gt;</span>
        <span style="color: #008000;">/// &lt;param name="sheetIndex"&gt;&lt;/param&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> GetDocumentData(IOpenXmlHandler handler, <span style="color: #2b91af;">int</span> sheetIndex)
        {
            <span style="color: #0000ff;">switch</span> (handler.TemplateId)
            {
                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"RowRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            <span style="color: #008000;">// you can get from web service etc., for simple, here just new a data model </span>
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                            <span style="color: #0000ff;">new</span> RowRangeServiceData1());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;

<strong>                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"RowListRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> RowListRangeServiceData());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;
</strong>            }
        }</pre>
</div>
<p><strong>3.6.4 <a name="3.6.4">Data model of Template range example 3</a></strong><br />
In this example, the template range has a list, and list&#8217;s element is also a list. Let us see the data model how to construct.<br />
As you have seen, entry class ComplexRowCloneRangeServiceData has metadata ExcelRange(&#8220;ROOT&#8221;), its member MasterDoorList1  has  metadata  [ExcelRange("PARENTLIST1")], MasterDoorList1 is a list.  MasterDoorList1&#8242;s element is RoomTypeList1 which has a member MasterDoorChildList, and MasterDoorChildList has metadata [ExcelRange("CHILDLIST1")], it is also a list. In the OnGetDocumentData event handler we added code to get data provider manager. For the others no need to change.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;

<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data
{
    <strong>[ExcelRange("ROOT")]</strong>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">ComplexRowCloneRangeServiceData</span>
    {
        <span style="color: #0000ff;">public</span> ComplexRowCloneRangeServiceData()
        {
            CreateDataForDemo();
        }
        <strong>[ExcelRange("PARENTLIST1")]</strong>
        <span style="color: #0000ff;">public</span> IList&lt;RoomTypeList1&gt; MasterDoorList1 = <span style="color: #0000ff;">new</span> List&lt;RoomTypeList1&gt;();
    }
}</pre>
</div>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data
{
    <span style="color: #008000;">/// &lt;summary&gt;</span>
    <span style="color: #008000;">/// 戸当りマスタ登録・変更画面の概要説明です。</span>
    <span style="color: #008000;">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">RoomTypeList1</span>
    {
        <span style="color: #0000ff;">public</span> RoomTypeList1()
        {
            CreateDataForDemo();
        }

        <span style="color: #0000ff;">public</span> RoomTypeList1(<span style="color: #2b91af;">string</span> houseNumber)
        {
            CreateDataForDemo2(houseNumber);
        }

        [Excel("部屋数1")]
        <span style="color: #0000ff;">public</span> <span style="color: #2b91af;">string</span> HouseNumber=<span style="color: #a31515;">"12"</span>;

        <strong>[ExcelRange("CHILDLIST1")]</strong>
        <span style="color: #0000ff;">public</span> IList&lt;RowRangeServiceData1&gt; MasterDoorChildList = <span style="color: #0000ff;">new</span> List&lt;RowRangeServiceData1&gt;();
    }
}</pre>
</div>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;
<span style="color: #0000ff;">using</span> System.Configuration;
<span style="color: #0000ff;">using</span> System.IO;
<span style="color: #0000ff;">using</span> System.Reflection;

<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Handler;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Data;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Config;

<span style="color: #0000ff;">using</span> OpenXmlDemoData.DataProvider;
<span style="color: #0000ff;">using</span> OpenXmlDemoData.Data;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData
{
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">DataService</span>
    {

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Assign a data provider manager or data range provider to a template for specified template id</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;param name="handler"&gt;&lt;/param&gt;</span>
        <span style="color: #008000;">/// &lt;param name="sheetIndex"&gt;&lt;/param&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> GetDocumentData(IOpenXmlHandler handler, <span style="color: #2b91af;">int</span> sheetIndex)
        {
            <span style="color: #0000ff;">switch</span> (handler.TemplateId)
            {
                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"RowRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            <span style="color: #008000;">// you can get from web service etc., for simple, here just new a data model </span>
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                            <span style="color: #0000ff;">new</span> RowRangeServiceData1());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;

                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"RowListRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> RowListRangeServiceData());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;

                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"ComplexRowCloneRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> ComplexRowCloneRangeServiceData());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;
            }
        }</pre>
</div>
<p><strong>3.6.5. <a name="3.6.5">How to create your class of IRangeDataProvider </a></strong><br />
If you need to search data from database, web service or other services in background, you might want to create your own implementation class of IRangeDataProvider. If your searched result is designed as data model demonstrated in the example above, the most convenient way is to create a sub class of DataModelRangeDataProvider. DataModelRangeDataProvider performs interface methods of IRangeDataProvider, but ReadRangeData() and WriteRangeData() do nothing. You can override these two methods in your way. When you open or parse document, firstly, IDataProviderManager calls ReadRangeData() to get data, then IDataProviderManager parses gotten data. When you save edited document by calling ExcelHandler or OpenXmlHandler&#8217;s Save() method, firstly, the Save() method will call Flush() method to save edited data into mapped data model of RangeData then call WriteRangeData() to save RangeData to database or other services.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;
<span style="color: #0000ff;">using</span> System.IO;
<span style="color: #0000ff;">using</span> System.Reflection;

<span style="color: #0000ff;">using</span> JanaBiz.Common.Serialize;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Data;
<span style="color: #0000ff;">using</span> OpenXmlDemoData.Data.Boat;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.DataProvider
{
    <span style="color: #008000;">/// &lt;summary&gt;</span>
    <span style="color: #008000;">/// </span>
    <span style="color: #008000;">/// This is demo for getting data from database or background service.</span>
    <span style="color: #008000;">/// Here we get data from xml resource file.</span>
    <span style="color: #008000;">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">ColumnDataProvider</span> : DataModelRangeDataProvider
    {

        <span style="color: #0000ff;">public</span> ColumnDataProvider()
            : <span style="color: #0000ff;">base</span>()
        {
        }

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Here you can call database service, web service of other background service to </span>
        <span style="color: #008000;">/// read data, the last step is assign the result data to RangeData.</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">override</span> <span style="color: #0000ff;">void</span> ReadRangeData()
        {
            <span style="color: #008000;">//here, read from xml file</span>
            Assembly assembly = Assembly.GetExecutingAssembly();
            <span style="color: #2b91af;">string</span> assemblyNamespace = assembly.FullName.Split(<span style="color: #0000ff;">new</span> <span style="color: #2b91af;">char</span>[]{<span style="color: #a31515;">','</span>})[0];
            <span style="color: #2b91af;">string</span> xmlfile = assemblyNamespace + <span style="color: #a31515;">".Resources.ColumnRangeTestData.xml"</span>;
            Stream stream = assembly.GetManifestResourceStream(xmlfile);
            BoatRace boatRace = Serializer.ReadModel&lt;BoatRace&gt;(stream);

            <span style="color: #008000;">//this must be done </span>
            <span style="color: #0000ff;">this</span>.RangeData = boatRace;
        }

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// You can write your saving data in your way.</span>
        <span style="color: #008000;">/// Here we just write the data into a xml file </span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;returns&gt;return true, if saved data successfully, otherwise false&lt;/returns&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">override</span> <span style="color: #2b91af;">bool</span> WriteRangeData()
        {
            Serializer.WriteToXml(<span style="color: #0000ff;">this</span>.RangeData, <span style="color: #a31515;">"c:\\ColumnListRangeTestData.xml"</span>);
            <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span>;
        }

    }
}</pre>
</div>
<p>In the example on the above, for simply demo, ColumnDataProvider just get data from a serialized xml resource file and write edited data into xml resource file. Next code is show how to assign the data provider to IDataProviderManager.<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Assign a data provider manager or data range provider to a template for specified template id</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;param name="handler"&gt;&lt;/param&gt;</span>
        <span style="color: #008000;">/// &lt;param name="sheetIndex"&gt;&lt;/param&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> GetDocumentData(IOpenXmlHandler handler, <span style="color: #2b91af;">int</span> sheetIndex)
        {
            <span style="color: #0000ff;">switch</span> (handler.TemplateId)
            {
                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"RowRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            <span style="color: #008000;">// you can get from web service etc., for simple, here just new a data model </span>
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                            <span style="color: #0000ff;">new</span> RowRangeServiceData1());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;

<strong>                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"ColumnListRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> ColumnDataProvider());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;
                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"ColumnCloneRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> ColumnDataProvider());
                            <span style="color: #0000ff;">break</span>;
                        <span style="color: #0000ff;">case</span> 1:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> ColumnDataProvider());
                            <span style="color: #0000ff;">break</span>;

                    }
                    <span style="color: #0000ff;">break</span>;
                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"ComplexColumnCloneRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> ComplexColumnDataProvider());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;

                <span style="color: #0000ff;">case</span> <span style="color: #a31515;">"ComplexColumnListRangeServiceTest"</span>:
                    <span style="color: #0000ff;">switch</span> (sheetIndex)
                    {
                        <span style="color: #0000ff;">case</span> 0:
                            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                                <span style="color: #0000ff;">new</span> ComplexColumnDataProvider());
                            <span style="color: #0000ff;">break</span>;
                    }
                    <span style="color: #0000ff;">break</span>;
</strong>            }
        }</pre>
</div>
<p><strong>3.6.6. <a name="3.6.6">Use Metadata without template range configuration</a></strong><br />
If you don&#8217;t want to create template configuration file, you can write necessary information into ExcelRange metadata as the following.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;
<span style="color: #0000ff;">using</span> JanaBiz.Common.Serialize;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data.Boat
{
    [Serializable]
    <strong>[ExcelRange("ROOT", "B5", "EQ10", "RowRangeService")]</strong>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">BoatRace</span>
    {
        <span style="color: #0000ff;">public</span> BoatRace()
        {
        }

        <strong>[ExcelRange("HEADER", "CX4", "DF48", "BlockRangeService")]</strong>
        <span style="color: #0000ff;">public</span> BoatRaceHeader HeaderData = <span style="color: #0000ff;">new</span> BoatRaceHeader();

        <strong>[ExcelRange("LIST", "BZ4", "CK48", "ColumnListRangeServiceRL")]</strong>
        <span style="color: #0000ff;">public</span> SerializableList&lt;BoatRaceRecord&gt; itemDataList =
           <span style="color: #0000ff;">new</span> SerializableList&lt;BoatRaceRecord&gt;();

        <strong>[ExcelRange("RESULT", "H4", "Q48", "BlockRangeService")]</strong>
        <span style="color: #0000ff;">public</span> BoatRaceResult ResultData = <span style="color: #0000ff;">new</span> BoatRaceResult();
    }
}</pre>
</div>
<p>Then  set parameter of method ParseTemplate(params bool[] usingConfig) to false,  handler.ParseTemplate(false);</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;

<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Handler;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Config;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Data;
<span style="color: #0000ff;">using</span> OpenXmlDemoData;

<span style="color: #0000ff;">namespace</span> TemplateConvertDemo
{
    <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">Program</span>
    {
        <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> Main(<span style="color: #2b91af;">string</span>[] args)
        {
            <span style="color: #008000;">//create your handler </span>
            IOpenXmlHandler handler = <span style="color: #0000ff;">new</span> OpenXmlHandler();

            <span style="color: #008000;">//tell ExcelTDF which ITemplateService is used to </span>
            <span style="color: #008000;">//get template file and template range configuration</span>
            handler.GetTemplateService&lt;LocalTemplateService&gt;();

            <span style="color: #008000;">//tell ExcelTDF which IDataProviderManager and </span>
            <span style="color: #008000;">//what data model is used to data              </span>
            handler.DataProviderManager = <span style="color: #0000ff;">new</span> DataModelProviderManager(
                <span style="color: #0000ff;">new</span> OpenXmlDemoData.Data.RowRangeServiceData1());

            <span style="color: #008000;">//set template id to identify which template is used</span>
            handler.TemplateId = <span style="color: #a31515;">"RowRangeServiceTest"</span>;

            <span style="color: #008000;">//parse your template </span>
            <strong>handler.ParseTemplate(<span style="color: #0000ff;">false</span>);</strong>

            <span style="color: #008000;">//parse your data </span>
            handler.ParseWorkbook(<span style="color: #0000ff;">null</span>);

            <span style="color: #008000;">//get parsed document</span>
            <span style="color: #2b91af;">byte</span>[] doc = handler.GetParsedDocument();

            <span style="color: #008000;">//release some resource</span>
            handler.Close();
        }
    }
}</pre>
</div>
<p><strong>4. <a name="4">Service</a></strong></p>
<p>ExcelTDF provides many range service to process template range as what you want to. Range service are the implementation class of IExcelRangeService and set in template range configuration file. Simultaneously ExcelTDF provides some custom cell services and function services. As explained on the chapter of Custom service variable, cell services and function services has the writing format as the same as Excel formula. Custom cell services are used to perform special processing like barcode, page break and so on, there are no result returned. Function service does some special processing and returns function result as string. Simply, range service is used to process template range, custom service is used to process template cells.</p>
<p><strong>4.1. <a name="4.1">IExcelRangeService</a></strong><br />
Default range service is configured in Spring.NET objects file included in ExcelTDF package as resource file. Service name which is called ServiceId in template range is object id that is upper case and lower case sensitive.<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">&lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"RowRangeService"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.Service.RowRangeService, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>/&gt;</pre>
</div>
<p>OpenXmlContext class provides some static methods to get ids of different services. You can get all range service ids by<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">OpenXmlContext.GetRangeServiceIds();</pre>
</div>
<p>ExcelTDF full versions provides following range services.<br />
<strong> </strong><br />
	<strong><a href="#4.1.1"> . RowRangeService</a></strong><br />
	<strong><a href="#4.1.2"> . RowListRangeService</a></strong><br />
	<strong><a href="#4.1.3"> . RowCloneRangeService</a></strong><br />
	<strong><a href="#4.1.4"> . ComplexRowListRangeService</a></strong><br />
	<strong><a href="#4.1.5"> . ComplexRowCloneRangeService</a></strong><br />
	<strong><a href="#4.1.6"> . BlockRangeService</a></strong><br />
	<strong><a href="#4.1.7"> . BlockRowListRangeService</a></strong><br />
	<strong><a href="#4.1.8"> . ComplexBlockRowListRangeService</a> </strong><br />
	<strong><a href="#4.1.9"> . ColumnListRangeService</a></strong><br />
	<strong><a href="#4.1.10"> . ColumnListRangeServiceRL</a></strong><br />
	<strong><a href="#4.1.11"> . ColumnCloneRangeService</a></strong><br />
	<strong><a href="#4.1.12"> . ColumnCloneRangeServiceRL</a></strong><br />
	<strong><a href="#4.1.13"> . ComplexColumnListRangeService</a></strong><br />
	<strong><a href="#4.1.14"> . ComplexColumnListRangeServiceRL</a></strong><br />
	<strong><a href="#4.1.15"> . ComplexColumnCloneRangeService</a></strong><br />
	<strong><a href="#4.1.16"> . ComplexColumnCloneRangeServiceRL</a></strong><br />
	<strong><a href="#4.1.17"> . MultiplePageRangeService</a></strong><br />
	<strong><a href="#4.1.18"> . BlockRowCloneRangeService</a></strong><br />
	<strong><a href="#4.1.19"> . BlockColumnCloneRangeService</a></strong><br />
<strong> </strong></p>
<p><strong>4.1.1. <a name="4.1.1">RowRangeService</a></strong><br />
RowRangeService is the simplest service whose range is specified by top row index and bottom row index. RowRangeService replaces the variables in template range with data value in RangeData of IRangeDataProvider. If you specify range by cell name of LeftTop and RightBottom, the variables outside the specified column will not be processed.<br />
The template range specified with this service is able to have child ranges. Generally, the worksheet&#8217;s root range is usually specified by this service.</p>
<p><strong>4.1.2. <a name="4.1.2">RowListRangeService</a></strong><br />
RowListRangeService is used to show a data list whose first element is specified by top row index and bottom row index. RowListRangeService requires you design well-formatted rows for all element in list. The template variable between top row and bottom row will be repeatedly processed until the last element of list. If you specify range by cell name of LeftTop and RightBottom, the variables outside the specified column will not be processed. The range specified service as RowListRangeService can not have child ranges (ExcelTDF not process any child ranges even child range is specified in template range configuration file). see <a href="#4.1.4">ComplexRowListRangeService</a><br />
In template, one element of list maybe have several excel rows as a logical unit. For example, if you specified template range from top row 8 to  bottom row 10, your logical unit is (10-8+1)=3 rows. Assume your data list size is 5, all data will be outputted from row 8 to row 8+3*5-1=22.  If you specify the StartIndex and PageSize in template range configuration, the elements from StartIndex to StartIndex+PageSize will be outputted. If StartIndex + PageSize is greater than the size of list, service outputs to the last element of list. The format of all output logical rows must be the same as the first element rows except that the template variable is only written in the first element rows. The best way is that you copy all cells in the first element several times until your list&#8217;s max size. Make sure cells exist in worksheet. At sometime the cell without text (blank cell ) might not be created in worksheet by Open XML even the cells is shown. See the following diagram of RowListRangeService example.  In template range configuration first element is defined from row index is from 8 to 10. list has max size 5.</p>
<p><a href="/wp-content/uploads/2010/09/t-rowlistservice2.png"><img class="aligncenter size-large wp-image-365" title="t-rowlistservice" src="/wp-content/uploads/2010/09/t-rowlistservice2-1024x516.png" alt="" width="640" height="322" /></a></p>
<p><strong>4.1.3. <a name="4.1.3">RowCloneRangeService</a></strong><br />
RowCloneRangeService is one of usually used service. RowCloneRangeService is used to show data list too. The different from RowListRangeService is RowCloneRangeService don&#8217;t have to set format for each elements except of first element rows. RowCloneRangeService clones cells in first element rows and add them in the below. This is very useful, you don&#8217;t worry about the list size and are able to design template simply.  After cloned row are added into document, the row index of other range and the cell name of formula will be changed, ExcelTDF will recalculate row index about them again. The RowCloneRangeService can not have child ranges as the same as RowListRangeService.<br />
The following is an example. At the bottom of template, there are a Excel formula of =SUM(E21:L25) and a pull down cell. After template is processed, 99 logical unit rows are cloned. The logical row size is 3, so the number of changed rows is 99*3=297. Let us see the formula in the result diagram, SUM(E21:L25) is changed to SUM(E318:L324) and the pull down cell also is moved from row 21 to row 318 too. If RowCloneRangeService is used, the row index of objects on the below of RowCloneRangeService range will be changed automatically, you don&#8217;t have to do any work to correct row index, ExcelTDF does all for you.</p>
<p><a href="/wp-content/uploads/2010/09/t-rowrangeservice2.png"><img class="aligncenter size-full wp-image-375" title="t-rowrangeservice2" src="/wp-content/uploads/2010/09/t-rowrangeservice2.png" alt="" width="823" height="417" /></a></p>
<p>The result processed by RowCloneRangeService is shown in the following.</p>
<p><a href="/wp-content/uploads/2010/09/d-rowclonerange.png"><img class="aligncenter size-full wp-image-373" title="d-rowclonerange" src="/wp-content/uploads/2010/09/d-rowclonerange.png" alt="" width="820" height="612" /></a></p>
<p><strong>4.1.4. <a name="4.1.4">ComplexRowListRangeService</a></strong><br />
ComplexRowListRangeService is a list service like RowListRangeService. The difference between ComplexRowListRangeService and RowListRangeService is that the element of ComplexRowListRangeService&#8217;s list data is able to include child ranges and child range is able to be any range type. RowListRangeService&#8217;s element is not able to include child ranges. Because ComplexRowListRangeService is also a list service, you must design the format for all elements in list as the same way as RowListRangeService. See the following template file, template range configuration and data model. The first element of ComplexRowListRangeService is from C4 to BJ22 and named as PARENTLIST1, other elements are well-designed as the same as the first element. In the element there is a RowListRangeService which is from C8 to BE10 and named as CHILDLIST1. CHILDLIST1&#8242;s maximum data size is 5 in first element of  PARENTLIST1.</p>
<p><a href="/wp-content/uploads/2010/09/t-complexrowlistrange.png"><img class="aligncenter size-full wp-image-383" title="t-complexrowlistrange" src="/wp-content/uploads/2010/09/t-complexrowlistrange.png" alt="" width="804" height="623" /></a></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span>
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span> &gt;
    <span style="color: #008000;">&lt;!-- sheet 1 --&gt;</span>
      &lt;object id=<span style="color: #a31515;">"ComplexRowListRangeServiceTest_SHEET1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
        &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ROOT"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"A1"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"CK275"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
           	&lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
           		&lt;ref object=<span style="color: #a31515;">"CRLRS_PARENTLIST1"</span>/&gt;
        	&lt;/list&gt;
        &lt;/property&gt;
      &lt;/object&gt;

       &lt;object id=<span style="color: #a31515;">"CRLRS_PARENTLIST1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
        &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"PARENTLIST1"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"C4"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BJ22"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"ComplexRowListRangeService"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
           	&lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        		&lt;ref object=<span style="color: #a31515;">"CRLRS_CHILDLIST1"</span>/&gt;
        	&lt;/list&gt;
        &lt;/property&gt;
      &lt;/object&gt;

      &lt;object id=<span style="color: #a31515;">"CRLRS_CHILDLIST1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
        &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"CHILDLIST1"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"C8"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BE10"</span>/&gt;
        &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowListRangeService"</span>/&gt;
      &lt;/object&gt;
&lt;/objects&gt;</pre>
</div>
<p><a href="/wp-content/uploads/2010/09/d-complexrowlistrange.png"><img class="aligncenter size-full wp-image-384" title="d-complexrowlistrange" src="/wp-content/uploads/2010/09/d-complexrowlistrange.png" alt="" width="825" height="781" /></a></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;
<span style="color: #0000ff;">using</span> JanaBiz.Common.Serialize;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data
{

    [ExcelRange("ROOT")]
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">ComplexRowListRangeServiceData</span>
    {
        [ExcelRange("PARENTLIST1")]
        <span style="color: #0000ff;">public</span> SerializableList&lt;RoomTypeList1&gt; MasterDoorList1 = <span style="color: #0000ff;">new</span> SerializableList&lt;RoomTypeList1&gt;();

    }
}</pre>
</div>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data
{
    <span style="color: #008000;">/// &lt;summary&gt;</span>
    <span style="color: #008000;">/// </span>
    <span style="color: #008000;">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">RoomTypeList1</span>
    {
        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// variable</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        [Excel("部屋数1")]
        <span style="color: #0000ff;">public</span> <span style="color: #2b91af;">string</span> HouseNumber=<span style="color: #a31515;">"12"</span>;

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Child list range </span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        [ExcelRange("CHILDLIST1")]
        <span style="color: #0000ff;">public</span> IList&lt;RowRangeServiceData1&gt; MasterDoorChildList = <span style="color: #0000ff;">new</span> List&lt;RowRangeServiceData1&gt;();

    }
}</pre>
</div>
<p><strong>4.1.5. <a name="4.1.5">ComplexRowCloneRangeService</a></strong><br />
ComplexRowCloneRangeService is a list clone service like RowCloneRangeService. The difference between ComplexRowCloneRangeService and RowCloneRangeService is that the element of ComplexRowCloneRangeService&#8217;s list data is able to include child ranges and child range is able to be any range type. RowCloneRangeService&#8217;s element is not able to include child ranges. See the following template file, template range configuration and data model. Using ComplexRowCloneRangeService, your template design becomes very simple. As the same as service of RowCloneRangeService, you don&#8217;t have to copy the format for each element rows in the list. Following example is explained on the above of Template range example 3.<br />
Let&#8217;s see more detail. ComplexRowCloneRangeService processes the range named PARENTLIST1 from B5 to BJ11, which has a RowCloneRangeService range from C8 to BE10 with color of green named CHILDLIST1.</p>
<p>The cell AA11&#8242;s template variable expression is #C{S4=SUM(SHⅡ本体)}, it is  in the range of PARENTLIST1. The variable name is S4 and referenced variable is SHⅡ本体 which is in the child range of CHILDLIST1. In the first element of PARENTLIST1, the child list has 5 elements, so the variable cells of SHⅡ本体 is AA8,AA11,AA14,AA17,AA20 and the result of formula is =SUM(AA8,AA11,AA14,AA17,AA20). Please see the other variables on the template S1, S1, S2..S10,S11, their behavior are the same as S4.</p>
<p>The cell  C11 in the range of PARENTLIST1 is normal formula, you can see it is become =SUM(L23:BE23), because row index is changed. It is the sum of S1..S11.</p>
<p>See the cells of AZ15, BE15, they are the variables expression #C{=SUM(S10)} and #C{=SUM(NWS本体)}. These two variables are in the range of ROOT. See the result on the diagram and what formula they have been changed to.</p>
<p><a href="/wp-content/uploads/2010/09/t-complexrowclonerange2.png"><img class="aligncenter size-full wp-image-401" title="t-complexrowclonerange" src="/wp-content/uploads/2010/09/t-complexrowclonerange2.png" alt="" width="962" height="375" /></a></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">&lt;?xml version=<span style="color: #a31515;">"1.0"</span> encoding=<span style="color: #a31515;">"utf-8"</span>?&gt;
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span> &gt;
  &lt;!-- sheet 1 --&gt;
  &lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"ComplexRowCloneRangeServiceTest_SHEET1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"ROOT"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"Top"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"1"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"Bottom"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"18"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"RowRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;<span style="color: #0000ff;">ref</span> <span style="color: #2b91af;">object</span>=<span style="color: #a31515;">"CRCRS_PARENTLIST1"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af;">object</span>&gt;

  &lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"CRCRS_PARENTLIST1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"PARENTLIST1"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"B5"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"BJ11"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"ComplexRowCloneRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;<span style="color: #0000ff;">ref</span> <span style="color: #2b91af;">object</span>=<span style="color: #a31515;">"CRCRS_CHILDLIST1"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af;">object</span>&gt;

  &lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"CRCRS_CHILDLIST1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"CHILDLIST1"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"C8"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"BE10"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"RowCloneRangeService"</span>/&gt;
  &lt;/<span style="color: #2b91af;">object</span>&gt;

&lt;/objects&gt;</pre>
</div>
<p><a href="/wp-content/uploads/2010/09/d-complexrowclonerange.gif"><img class="alignleft size-full wp-image-397" title="d-complexrowclonerange" src="/wp-content/uploads/2010/09/d-complexrowclonerange.gif" alt="" width="960" height="720" /></a><br />
<a href="/wp-content/uploads/2010/09/d-complexrowclonerange-21.png"><img class="aligncenter size-full wp-image-405" title="d-complexrowclonerange-2" src="/wp-content/uploads/2010/09/d-complexrowclonerange-21.png" alt="" width="939" height="502" /></a></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data
{

    [ExcelRange("ROOT")]
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">ComplexRowCloneRangeServiceData</span>
    {
        <span style="color: #0000ff;">public</span> ComplexRowCloneRangeServiceData()
        {
            CreateDataForDemo();
        }

        [ExcelRange("PARENTLIST1")]
        <span style="color: #0000ff;">public</span> IList&lt;RoomTypeList1&gt; MasterDoorList1 = <span style="color: #0000ff;">new</span> List&lt;RoomTypeList1&gt;();

    }
}</pre>
</div>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data
{
    <span style="color: #008000;">/// &lt;summary&gt;</span>
    <span style="color: #008000;">/// </span>
    <span style="color: #008000;">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">RoomTypeList1</span>
    {
        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// variable</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        [Excel("部屋数1")]
        <span style="color: #0000ff;">public</span> <span style="color: #2b91af;">string</span> HouseNumber=<span style="color: #a31515;">"12"</span>;

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Child list range </span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        [ExcelRange("CHILDLIST1")]
        <span style="color: #0000ff;">public</span> IList&lt;RowRangeServiceData1&gt; MasterDoorChildList = <span style="color: #0000ff;">new</span> List&lt;RowRangeServiceData1&gt;();

    }
}</pre>
</div>
<p><strong>4.1.6. <a name="4.1.6">BlockRangeService</a></strong><br />
BlockRangeService is as the same as RowRangeService except that the range is specified by cell name. It is a service to process a rectangle region. If you only want to process some special region by service, BlockRangeService is very useful. You can split your complicated template into some simple region to process one by one. The range of RowRangeService is able to be specified by cell name too. In this case RowRangeService has the same action as BlockRangeService. About more detail see RowRangeService.</p>
<p><strong>4.1.7. <a name="4.1.7">BlockRowListRangeService</a></strong><br />
BlockRowListRangeService is the same as RowListRangeService except that the range is specified by cell name. It is also a service to process a rectangle region, but in the region, data is output as list by rows. If the range of RowListRangeService is specified by cell name, RowListRangeService has the same action as BlockRowListRangeService. About more detail, see RowListRangeService.</p>
<p><strong>4.1.8. <a name="4.1.8">ComplexBlockRowListRangeService</a></strong><br />
CpmplexBlockRowListRangeService is a list service whose range is defined by cell name and is able to have child ranges in the list elements. The behavior is like ComplexRowListRangeService. About more detail, see <a href="#4.1.4">ComplexRowListRangeService</a>.</p>
<p><strong>4.1.9-10. <a name="4.1.9">ColumnListRangeService</a> and <a name="4.1.10">ColumnListRangeServiceRL</a></strong><br />
ColumnListRangeService is similar to the RowListRangeService but the range is specified by column index. ColumnListRangeService outputs data from left to right as list. The first element is outputted on the left side of the range. In the opposite, the ColumnListRangeServiceRL outputs data from right to the left. The first element is outputted on the right side of the range. As the same as service of RowListRangeService, you must make sure all element&#8217;s columns have the same format.  See the diagram following, the gray region is processed by ColumnListRangeServiceRL.<br />
<a href="/wp-content/uploads/2010/09/t-columnlistrange.png"><img class="aligncenter size-full wp-image-417" title="t-columnlistrange" src="/wp-content/uploads/2010/09/t-columnlistrange.png" alt="" width="710" height="519" /></a></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">&lt;?xml version=<span style="color: #a31515;">"1.0"</span> encoding=<span style="color: #a31515;">"utf-8"</span>?&gt;
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span>&gt;
  &lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"ColumnListRangeServiceTest_SHEET1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"ROOT"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"B2"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"EQ50"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"RowRangeService"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;<span style="color: #0000ff;">ref</span> <span style="color: #2b91af;">object</span>=<span style="color: #a31515;">"ColumnListRangeServiceTest_1_HEADER"</span> /&gt;
        &lt;<span style="color: #0000ff;">ref</span> <span style="color: #2b91af;">object</span>=<span style="color: #a31515;">"ColumnListRangeServiceTest_1_LIST"</span> /&gt;
        &lt;<span style="color: #0000ff;">ref</span> <span style="color: #2b91af;">object</span>=<span style="color: #a31515;">"ColumnListRangeServiceTest_1_RESULT"</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/<span style="color: #2b91af;">object</span>&gt;
  &lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"ColumnListRangeServiceTest_1_HEADER"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"HEADER"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"CX4"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"DF48"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"BlockRangeService"</span> /&gt;
  &lt;/<span style="color: #2b91af;">object</span>&gt;
  &lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"ColumnListRangeServiceTest_1_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"BZ4"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"CK48"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"ColumnListRangeServiceRL"</span> /&gt;
  &lt;/<span style="color: #2b91af;">object</span>&gt;
  &lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"ColumnListRangeServiceTest_1_RESULT"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"RESULT"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"H4"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"Q48"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> <span style="color: #0000ff;">value</span>=<span style="color: #a31515;">"BlockRangeService"</span> /&gt;
  &lt;/<span style="color: #2b91af;">object</span>&gt;

&lt;/objects&gt;</pre>
</div>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;
<span style="color: #0000ff;">using</span> JanaBiz.Common.Serialize;

<span style="color: #0000ff;">namespace</span> OpenXmlDemoData.Data.Boat
{
    [Serializable]
    [ExcelRange("ROOT")]
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">BoatRace</span>
    {
        <span style="color: #0000ff;">public</span> BoatRace()
        {
        }

        [ExcelRange("HEADER")]
        <span style="color: #0000ff;">public</span> BoatRaceHeader HeaderData = <span style="color: #0000ff;">new</span> BoatRaceHeader();

        [ExcelRange("LIST")]
        <span style="color: #0000ff;">public</span> SerializableList&lt;BoatRaceRecord&gt; itemDataList =
           <span style="color: #0000ff;">new</span> SerializableList&lt;BoatRaceRecord&gt;();

        [ExcelRange("RESULT")]
        <span style="color: #0000ff;">public</span> BoatRaceResult ResultData = <span style="color: #0000ff;">new</span> BoatRaceResult();
    }
}</pre>
</div>
<p><strong>4.1.11-12. <a name="4.1.11">ColumnCloneRangeService</a> and <a name="4.1.12">ColumnCloneRangeServiceRL</a></strong><br />
<a href="/wp-content/uploads/2010/09/t-columnclonerange.png"><img class="alignright size-full wp-image-420" title="t-columnclonerange" src="/wp-content/uploads/2010/09/t-columnclonerange.png" alt="" width="371" height="521" /></a><br />
ColumnCloneRangeService is similar to the RowCloneRangeService but the range is specified by column index. ColumnCloneRangeService clones specified columns and add cloned columns one by one from left to right. In the opposite, the ColumnCloneRangeServiceRL clones specified columns and add cloned columns one by one from right to left like the Japanese newspaper. Using ColumnCloneRangeService you don&#8217;t have to copy all elements format as ColumnListRangeService. After processed, column index of some ranges, formulas, objects will be recalculated and moved automatically.</p>
<p>The result is shown in the following.<br />
<a href="/wp-content/uploads/2010/09/d-columnclonerange.png"><img class="aligncenter size-full wp-image-424" title="d-columnclonerange" src="/wp-content/uploads/2010/09/d-columnclonerange.png" alt="" width="702" height="510" /></a></p>
<p><strong>4.1.13-14. <a name="4.1.13">ComplexColumnListRangeService</a> and <a name="4.1.14">ComplexColumnListRangeServiceRL</a></strong><br />
ComplexColumnListRangeService is a list service like ColumnListRangeService. The difference between ComplexColumnListRangeService and ColumnListRangeService is that the element of ComplexColumnListRangeService’s list data is able to include child ranges and child range is able to be any range type. ColumnListRangeService’s element is not able to include child ranges. Because ComplexColumnListRangeService is also a list service, you must design the format for all elements in list as the same way as ColumnListRangeService. If in the element of ComplexColumnListRangeService there is a child range using ColumnListRangeService, make sure each element’s format is designed well too. See the following template file, template range configuration and data model.</p>
<p>Here ROOT range has two child ranges named TITLE and DATA. TITLE is a BlockRangeService and has one child range SIMAI which is processed by service BlockRowListRangeService. Let us see DATA range in detail. DATA range is processed by ComplexColumnListRangeService which has four child ranges; those of them are processed by BlockRowListRangeService. To understand how it works, please check the each child range&#8217;s region. ComplexColumnListRangeService adds the data from left to right. In the contrary, ComplexColumnListRangeServiceRL processes the data from right to left.</p>
<p>The following is the part of template.</p>
<p><a href="/wp-content/uploads/2010/09/t-complexcolumnlistrange2.png"><img class="aligncenter size-full wp-image-431" title="t-complexcolumnlistrange" src="/wp-content/uploads/2010/09/t-complexcolumnlistrange2.png" alt="" width="749" height="817" /></a></p>
<p>Here is the template range configuration file.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span>
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span>&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_SHEET1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ROOT"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"A1"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"IR147"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_ROOT_TITLE"</span> /&gt;
        &lt;ref object=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_ROOT_DATA"</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_ROOT_TITLE"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"TITLE"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B2"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"K147"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRangeService"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_TITLE_SIMAI"</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_TITLE_SIMAI"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"SIMAI"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B32"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"B46"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_ROOT_DATA"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"DATA"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L2"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"U147"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"ComplexColumnListRangeService"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_NAME_LIST"</span> /&gt;
        &lt;ref object=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_DA_LIST"</span> /&gt;
        &lt;ref object=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_BAJYU_LIST"</span> /&gt;
        &lt;ref object=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_DA2_LIST"</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_NAME_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"NAME_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L32"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"L33"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_DA_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"DA_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L58"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"S59"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_BAJYU_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"BAJYU_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L66"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"U81"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnListRangeServiceTest_1_DATA_DA2_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"DA2_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L120"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"T121"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
&lt;/objects&gt;</pre>
</div>
<p>The result processed by ComplexColumnListRangeService is shown in the following.<br />
<a href="/wp-content/uploads/2010/09/d-complexcolumnlistrange.png"><img class="aligncenter size-full wp-image-433" title="d-complexcolumnlistrange" src="/wp-content/uploads/2010/09/d-complexcolumnlistrange.png" alt="" width="683" height="819" /></a></p>
<p><strong>4.1.15-16. <a name="4.1.15">ComplexColumnCloneRangeService</a> and <a name="4.1.16">ComplexColumnCloneRangeServiceRL</a></strong><br />
<a href="/wp-content/uploads/2010/09/t-complexcolumnclonerange.png"><img class="alignright size-full wp-image-438" title="t-complexcolumnclonerange" src="/wp-content/uploads/2010/09/t-complexcolumnclonerange.png" alt="" width="206" height="826" /></a><br />
ComplexColumnCloneRangeService is a list clone service like ColumnCloneRangeService. The difference between ComplexColumnCloneRangeService and ColumnCloneRangeService is that the element of ComplexColumnCloneRangeService’s list data is able to include child ranges and child range is able to be any range type. ColumnCloneRangeService’s element is not able to include child ranges. See the following template file, template range configuration and data model. Using ComplexColumnCloneRangeService, your template design becomes very simple. As the same as service of ColumnCloneRangeService, you don’t have to copy the format for each element rows in the list. Here we use ComplexColumnCloneRangeServiceRL to process the range of DATA, the cloned columns are added into the left of range DATA from right to left. The range of DATA has four child ranges. The child range of BAJYU_LIST has three elements; the first element region is from B66 to K81. Please check the output result. The column index of formulas and other objects in the right of range DATA will be changed, ExcelTDF automatically searches these objects and changes the column index of them.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span>
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span>&gt;
  &lt;object id=<span style="color: #a31515;">"ComplexColumnCloneRangeServiceTest_SHEET1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ROOT"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"A1"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"Q148"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"CCCRST_1_TITLE"</span> /&gt;
        &lt;ref object =<span style="color: #a31515;">"CCCRST_1_DATA"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"CCCRST_1_TITLE"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"TITLE"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L2"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"U147"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRangeService"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"CCCRST_1_SIMAI"</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"CCCRST_1_SIMAI"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"SIMAI"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L32"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"U33"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;  

  &lt;object id=<span style="color: #a31515;">"CCCRST_1_DATA"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"DATA"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B2"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"K147"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"ComplexColumnCloneRangeServiceRL"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"CCCRST_1_DA_LIST"</span> /&gt;
        &lt;ref object=<span style="color: #a31515;">"CCCRST_1_BAJYU_LIST"</span> /&gt;
        &lt;ref object=<span style="color: #a31515;">"CCCRST_1_DA2_LIST"</span> /&gt;
        &lt;ref object=<span style="color: #a31515;">"CCCRST_1_NAME_LIST"</span> /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"CCCRST_1_DA_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"DA_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"C58"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"I59"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"CCCRST_1_BAJYU_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"BAJYU_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B66"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"K81"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"CCCRST_1_DA2_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"DA2_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B120"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"K121"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"CCCRST_1_NAME_LIST"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"NAME_LIST"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B32"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"K33"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"CCCRST_SHEET2"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ROOT"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"A1"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BP41"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span> /&gt;
  &lt;/object&gt;
  &lt;object id=<span style="color: #a31515;">"CCCRST_SHEET3"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ROOT"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"A1"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BP41"</span> /&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span> /&gt;
  &lt;/object&gt;
&lt;/objects&gt;</pre>
</div>
<p>Following is the result document processed by ComplexCiolumnCloneRangeService.</p>
<p><a href="/wp-content/uploads/2010/09/d-complexcolumnclonerange.png"><img class="aligncenter size-full wp-image-446" title="d-complexcolumnclonerange" src="/wp-content/uploads/2010/09/d-complexcolumnclonerange.png" alt="" width="732" height="821" /></a></p>
<p><strong>4.1.17. <a name="4.1.17">MultiplePageRangeService</a></strong><br />
MultiplePageRangeService is created to process some complicated reports or excel documents which has multiple different page designs. Sometimes we want to create a report which has page header, page footer, report header and report footer. In ExcelTDF, you can considered them as some ranges. In fact, using RowRangeService or BlockRowRangeService, you can output header and footer information easily. If your document or report has only one page, you can do your design using services explained on the above. By assembling those services, ExcelTDF is able to output various documents and reports as what you want. If your report has more pages that all of them are the same design, you can use ComplexRowCloneRangeService or ComplexRowListRangeService to output your report page by page.  In this case, a page is an element of list. MultiplePageRangeService provides ability for creating document and report which has different page design while a list data might be outputted across all pages. Usually we want to output some summary information into the first page or last page, the detail information page by page. Depending on the size of list data, the number of pages to be outputted will be variable. MultiplePageRangeService controls these behaviors according to the properties set in the template range configuration file. MultiplePageRangeService is able to process document and report which has two or three different page designs.</p>
<p>Let us see following template, which has two reports, owner sales report and parking sales report. In the template, owner sales report has three different pages and parking sales report has one page. We want to output owner report and parking report for one owner in one worksheet. One owner maybe has a lot of parking, we need to output parking name, parking sales amount as one line for each parking in the owner report and output parking sales amount detail data in the parking report.</p>
<p>Download template <a href="/wp-content/uploads/2010/09/SalesReport1.xlsx">SalesReport</a></p>
<p><a href="/wp-content/uploads/2010/09/t-multitemplatepagerange.png"><img class="aligncenter size-full wp-image-455" title="t-multitemplatepagerange" src="/wp-content/uploads/2010/09/t-multitemplatepagerange.png" alt="" width="1236" height="608" /></a></p>
<p>Parking sales report template page is omitted.</p>
<p>The following is template range configuration file, download <a href="/wp-content/uploads/2010/09/SalesReport.zip">SalesReport</a><br />
In the worksheet, there are two child ranges, and they are owner report and parking report named OWNER_REPORT, PARKING_REPORT. Owner report range has three page child ranges, OWNER_PAGE1, OWNER_PAGE2, OWNER_PAGE3. For three page ranges, there is a list range of sales amount for each parking.  Assume the owner has 56 parkings, the list size will be 56. In the template configuration, the PageSize of the range PARK_DATA_LIST in OWNER_PAGE1, OWNER_PAGE2, OWNER_PAGE3 is 15, so the owner report will be output 4 pages. The property of IsRepeat in internal page OWNER_PAGE2, which is set to true, means this page is able to output repeated. ExcelTDF controls output behavior based on those properties. PARK_DATA_LIST range is outputted across all pages, this behavior is controlled by property of IsCrosssPage.  Besides owner report, each parking detail data is outputed as one page, thus in the worksheet we output owner report as 4 pages and parking report as 56 pages.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">&lt;?xml version="1.0" encoding="utf-8" ?&gt;</span>
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span> &gt;
  <span style="color: #008000;">&lt;!-- sheet 1 --&gt;</span>
  &lt;object id=<span style="color: #a31515;">"SalesReport_SHEET1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"SALES_REPORT"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B1"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BG209"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"OwnerReport"</span>/&gt;
        &lt;ref object=<span style="color: #a31515;">"ParkReport"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"OwnerReport"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"OWNER_REPORT"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B1"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BG150"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"MultiplePageRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"OwnerPage1"</span>/&gt;
        &lt;ref object=<span style="color: #a31515;">"OwnerPage2"</span>/&gt;
        &lt;ref object=<span style="color: #a31515;">"OwnerPage3"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"OwnerPage1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"OWNER_PAGE1"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span>   value=<span style="color: #a31515;">"B1"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BG50"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span>   value=<span style="color: #a31515;">"RowRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"ParkData1"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"ParkData1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"PARK_DATA_LIST"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B24"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BG24"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowListRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"PageSize"</span> value=<span style="color: #a31515;">"15"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"IsCrossPage"</span> value=<span style="color: #a31515;">"true"</span>/&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"OwnerPage2"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span>   value=<span style="color: #a31515;">"OWNER_PAGE2"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span>     value=<span style="color: #a31515;">"B51"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"AT100"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span>   value=<span style="color: #a31515;">"ComplexRowCloneRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"IsRepeat"</span>    value=<span style="color: #a31515;">"true"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"ParkData2"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"ParkData2"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"PARK_DATA_LIST"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B74"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"AJ74"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowListRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"PageSize"</span> value=<span style="color: #a31515;">"15"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"IsCrossPage"</span> value=<span style="color: #a31515;">"true"</span>/&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"OwnerPage3"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span>   value=<span style="color: #a31515;">"OWNER_PAGE3"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span>     value=<span style="color: #a31515;">"B101"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"AT150"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span>   value=<span style="color: #a31515;">"RowRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"ParkData3"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"ParkData3"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"PARK_DATA_LIST"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B124"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"AJ124"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowListRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"PageSize"</span> value=<span style="color: #a31515;">"15"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"IsCrossPage"</span> value=<span style="color: #a31515;">"true"</span>/&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"ParkReport"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"PARK_REPORT"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B151"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"AT209"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"ComplexRowCloneRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"AdditionItems"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"AdditionItems"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ADDITIONS"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"B192"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"AJ192"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"BlockRowListRangeService"</span>/&gt;
  &lt;/object&gt;

&lt;/objects&gt;</pre>
</div>
<p>Download the result of report  <a href="/wp-content/uploads/2010/09/SalesReport2.xlsx">SalesReport result</a></p>
<p>The following is a part of data model.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using JanaBiz.OpenXml;

namespace OpenXmlDemoData.Data
{
    /// &lt;summary&gt;
    /// sales report
    /// &lt;/summary&gt;
    [ExcelRange("SALES_REPORT")]
    public class SalesReportData
    {
        #region constructor

        public SalesReportData()
        {
        }

        #endregion

        /// &lt;summary&gt;
        /// all parking data of owner
        /// &lt;/summary&gt;
        [ExcelRange("OWNER_REPORT")]
        public OwnerSalesReport ownerReport = new OwnerSalesReport();

        /// &lt;summary&gt;
        /// sales data of parking
        /// &lt;/summary&gt;
        [ExcelRange("PARK_REPORT")]
        public IList&lt;OwnerParkSalesData&gt; ParkList
        {
            get { return ownerReport.ParkList; }
        }
    }
}</pre>
</div>
<p><strong>4.1.18. <a name="4.1.18">BlockRowCloneRangeService</a></strong><br />
BlockRowCloneRangeService is similar to the RowCloneRangeService. The difference is that BlockRowCloneRangeService clones only cells from specified top row to bottom row between specified columns, so the row index of cells that is between the specified columns and row index is greater than the bottom row will be moved after cloned rows are added.<br />
On the other hand, the RowCloneRangeService clones cells from specified top row to bottom row without the limitation of column and moves all cell&#8217;s index below the range itself after the cloned rows are added.</p>
<p><a href="/wp-content/uploads/2010/09/t-blockrowclonerange.png"><img class="aligncenter size-full wp-image-597" title="t-blockrowclonerange" src="/wp-content/uploads/2010/09/t-blockrowclonerange.png" alt="" width="684" height="558" /></a></p>
<p>The result is shown in the following, you can see the range B3 and K4 is cloned and added on the below. The cells that the column index is between column B and K and the row is greater than 4 are moved.</p>
<p><a href="/wp-content/uploads/2010/09/d-blockrowclonerange.png"><img class="aligncenter size-full wp-image-598" title="d-blockrowclonerange" src="/wp-content/uploads/2010/09/d-blockrowclonerange.png" alt="" width="692" height="601" /></a></p>
<p><strong>4.1.19. <a name="4.1.19">BlockColumnCloneRangeService</a></strong><br />
BlockColumnCloneRangeService is similar to the ColumnCloneRangeService. The difference is that BlockColumnCloneRangeService clones only cells from specified left column to right column between specified rows, so the column index of cells that is between the specified rows and greater than the right column will be moved after cloned columns are added.<br />
On the other hand, the ColumnCloneRangeService clones columns from specified left column to right column without row limitation, the columns index that is greater than the right column will be changed after cloned columns is added.</p>
<p><a href="/wp-content/uploads/2010/09/t-blockcolumnclonerange.png"><img class="aligncenter size-full wp-image-601" title="t-blockcolumnclonerange" src="/wp-content/uploads/2010/09/t-blockcolumnclonerange.png" alt="" width="780" height="524" /></a></p>
<p>The result is shown in the following, you can see the range B3 and C23 is cloned and added on the right. The cells that row is  between row 3 and 23 and column is greater than C are moved.</p>
<p><a href="/wp-content/uploads/2010/09/d-blockcolumnclonerange.png"><img class="aligncenter size-full wp-image-603" title="d-blockcolumnclonerange" src="/wp-content/uploads/2010/09/d-blockcolumnclonerange.png" alt="" width="898" height="517" /></a></p>
<p><strong>4.2. <a name="4.2">IExcelCellService &amp; IExcelFunctionService</a></strong><br />
In ExcelTDF, one of the most flexible functionality is that you can create your own custom service. Custom service lets you control your cell output in the template design, that is similar to the excel function. Custom service has two types. The implementation class of IExcelCellService is custom cell service while the implementation class of IExcelFunctionService is custom function service. Cell service has no return result, in the contrary, function service return a string as result. In the custom service, the parameter can be template variable, cell name, constant of text or number. The base class of ExcelCellServiceBase provides a lot of methods to get parameter&#8217;s cell name or values. On the above example of MultiplePageRangeService, we used  XSCHECKBOX, XSPAGEBREAK, XSBARCODE cell services and XFPRANGE and XFSRANGE function services. If parameter of service is cell name, the index of cell&#8217;s row and column will be recalculated. If the parameter of service is template variable, then ExcelTDF will search template variable&#8217;s cell name.<br />
ExcelTDF provides following cell services and function services now.</p>
<p><strong>4.2.1. <a name="4.2.1">Cell Service</a></strong></p>
<p><strong>4.2.1.1. <a name="4.2.1.1">XSCHAR</a></strong><br />
Output amount digit by digit.</p>
<p>Format:<br />
%{=XSCHAR(TEXT, 1|LEFT|left|0|RIGHT|right)}<br />
%{=XSCHAR(TEXT, 1|LEFT|left|0|RIGHT|right, LEADING)}<br />
%{=XSCHAR(TEXT, 1|LEFT|left|0|RIGHT|right, LEADING, TAILING)}<br />
where TEXT is a template variable or cell name or constant of number. Second parameter of 1|LEFT|left indicates that output digit from left to right(left alignment) start with the cell of this service. 0|RIGHT|right indicates that output digit from right to left (right alignment) start with the cell of this service. The third and fourth parameter is appended char on the beginning or ending of char, that maybe dollar marker etc.</p>
<p>Example:<br />
%{=XSCHAR(&#8220;123999&#8243;, 0, &#8220;$&#8221;)}, %{=XSCHAR(A4, 1, &#8220;$&#8221;, &#8220;-&#8221;)}</p>
<p><a href="/wp-content/uploads/2010/09/f-xschar1.png"><img class="aligncenter size-full wp-image-480" title="f-xschar" src="/wp-content/uploads/2010/09/f-xschar1.png" alt="" width="537" height="156" /></a></p>
<p><strong>4.2.1.2. <a name="4.2.1.2">XSCHECKBOX</a></strong><br />
Output a checkbox. The checkbox is not a vb control, it is just using some special font.</p>
<p>Format:<br />
%{=XSCHECKBOX(FLAG)}<br />
%{=XSCHECKBOX(FLAG,TEXT)}<br />
where FLAG is a flag to indicate checked or not, 1|true is checked, otherwise not checked. The second parameter of TEXT is a string after checkbox. Both FLAG and TEXT can be a template variable, cell name of constant string, number.</p>
<p>Example:<br />
%{=XSCHECKBOX(PARKTYPE)},  %{=XSCHECKBOX(PARKTYPE, PARKNAME)}<br />
In data model<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">[Excel("PARKTYPE")]
<span style="color: #0000ff;">public</span> <span style="color: #2b91af;">int</span> ParkType

[Excel("PARKNAME")]
<span style="color: #0000ff;">public</span> <span style="color: #2b91af;">string</span> ParkName</pre>
</div>
<p><a href="/wp-content/uploads/2010/09/f-checkbox.png"><img class="aligncenter size-full wp-image-483" title="f-checkbox" src="/wp-content/uploads/2010/09/f-checkbox.png" alt="" width="616" height="100" /></a></p>
<p><strong>4.2.1.3. <a name="4.2.1.3">XSBARCODE</a></strong><br />
XSBARCODE outputs bar code on the specified image. In order to output bar code you must add a image to template where your bar code will be output. Bar code will be output as the same size as image.</p>
<p>Format:<br />
%{=XSBARCODE(IMAGENAME, BARCODETEXT, TYPE)}<br />
%{=XSBARCODE(IMAGENAME, BARCODETEXT, TYPE, SHOW_LABEL)}<br />
IMAGENAME: the image name you have added into template<br />
BARCODETEXT: bar code string, which can be template variable, cell name or constant text, number<br />
TYPE:  bar code type<br />
SHOW_LABEL: 1 or true specify to output string of bar code text.</p>
<p>Following bar code types are supported:<br />
UCC12<br />
UPCA, UPC-A<br />
UCC13, EAN13, EAN-13<br />
Interleaved2of5<br />
Industrial2of5<br />
Standard2of5<br />
LOGMARS<br />
CODE39<br />
CODE39Extended<br />
Codabar<br />
PostNet<br />
ISBN,BOOKLAND<br />
JAN13,JAN-13<br />
UPC_SUPPLEMENTAL_2DIGIT<br />
MSI_Mod10,MSI_2Mod10,MSI_Mod11,MSI_Mod11_Mod10,Modified_Plessey<br />
UPC_SUPPLEMENTAL_5DIGIT,UPCE,UPC-E<br />
EAN8,EAN-8<br />
USD8,CODE11<br />
CODE128,CODE128A<br />
CODE128B,CODE128C<br />
ITF14,CODE93</p>
<p>Example:<br />
%{=XSBARCODE(&#8220;BCODE&#8221;, BARCODENO, &#8220;UPC-A&#8221;)}<br />
BCODE is image name that bar code image will replace it.</p>
<p><a href="/wp-content/uploads/2010/09/f-barcode1.png"><img class="aligncenter size-full wp-image-488" title="f-barcode1" src="/wp-content/uploads/2010/09/f-barcode1.png" alt="" width="621" height="121" /></a></p>
<p><a href="/wp-content/uploads/2010/09/f-barcode2.png"><img class="aligncenter size-full wp-image-489" title="f-barcode2" src="/wp-content/uploads/2010/09/f-barcode2.png" alt="" width="608" height="137" /></a></p>
<p><strong>4.2.1.4. <a name="4.2.1.4">XSPAGEBREAK</a></strong><br />
Add excel page break in the worksheet for document and report printing. XSPAGEBREAK is very useful for more page output.</p>
<p>Format:<br />
%{=XSPAGEBREAK}<br />
%{=XSPAGEBREAK(ROW|CELL|VAR)}<br />
If no parameter is specified , add page break on the row of this service written. If row or cell is specified add page break on the specified row. If template variable is specified, add page break on the row on which template variable is.</p>
<p>Example: %{=XSPAGEBREAK}<br />
On the example of service MultiplePageRangeService, XSPAGEBREAK is added in the template.<br />
XSPAGEBREAK are added on the last row in last page of owner report and parking report. Parking report is a page processed a clone service. When parking page is cloned, the page break will be added on the last row of cloned page.</p>
<p><a href="/wp-content/uploads/2010/09/f-pagebreak.png"><img class="aligncenter size-full wp-image-492" title="f-pagebreak" src="/wp-content/uploads/2010/09/f-pagebreak.png" alt="" width="453" height="673" /></a></p>
<p><strong>4.2.1.5. <a name="4.2.1.5">XSVDLIST</a></strong><br />
Set cell as pull down list. It is the same as the menu of Data/Data Input/List in the Excel.</p>
<p>Format:<br />
%{VAR=XSVDLIST(&#8220;A,B,C&#8221;|AJ12:AJ20|VARIABLE)}<br />
XSVDLIST is some different from services above. The left side variable name is the value of cell in pull down list while the parameter in expression of XSVDLIST is pull down items which is able to be a string with comma separated or cell range or variable which is in the list range. The value of VAR can be referenced by other expression and can be saved back into data model as other variables.</p>
<p>Example:<br />
%{ITEM=XSVDLIST(&#8220;iPod,iPhone,iPad&#8221;)}<br />
In data model:<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">[Excel("ITEM")]
<span style="color: #0000ff;">public</span> <span style="color: #2b91af;">string</span> Item {<span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span>;}</pre>
</div>
<p><a href="/wp-content/uploads/2010/09/f-vdlist.png"><img class="aligncenter size-full wp-image-495" title="f-vdlist" src="/wp-content/uploads/2010/09/f-vdlist.png" alt="" width="466" height="58" /></a></p>
<p><strong>4.2.2. <a name="4.2.2">Function Service</a></strong><br />
Custom function service can be used in expression of custom cell service, other custom function service and Excel formula.</p>
<p><strong>4.2.2.1. <a name="4.2.2.1">XFPRANGE</a></strong><br />
Search variable from specified parent range and return the cell name such as A12 or cell name string such as A12,A13,A14 if variable is in the list. Because that ExcelTDF search variable first from range of itself, then the child ranges, if you have the same variable name in different range, this function maybe useful, you can search variable from your specified range. Usually, in child range you can reference parent range&#8217;s variable directly by this function.</p>
<p>Format:<br />
%{=XFPRANGE(VAR)}<br />
%{=XFPRANGE(VAR, PARENT_LEVEL)}<br />
VAR: template variable to be searched<br />
PARENT_LEVEL: the number of parent hierarchy<br />
second parameter is the specified number from which parent range to search variable. For example, if the second parent is 2, search variable VAR from the parent&#8217;s parent range. If no second parameter is specified, search from parent range</p>
<p>Example:<br />
#C{=SUM(XFPRANGE(FURIKOMI, 1))}<br />
On the above MultiplePageRangeService, in the first page of owner report we want to output total sum of FURIKOMI which is across in the first page, internal page and last page. So we specified search FURIKOMI from parent range, that is OWNER_REPORT which includes all pages. FURIKOMI is a variable in a list, so SUM(XFPRANGE(FURIKOMI, 1)) is the total amount.</p>
<p><strong>4.2.2.2. <a name="4.2.2.2">XFSRANGE</a></strong><br />
Search variable from all brother ranges including itself and return the cell name such as A12 or cell name string such as A12,A13,A14 if variable is in the list.</p>
<p>Format:<br />
%{=XFSRANGE(VAR)}<br />
VAR is the variable to be searched.</p>
<p>Example:<br />
#C{小計=SUM(FURIKOMI)}<br />
#C{合計=SUM(XFSRANGE(小計))}<br />
On the above MultiplePageRangeService, in owner report, each page has a variable named 小計 which is the sum amount of parking in that page and in the last page there is a variable 合計 which is the sum of all 小計 in each page. You can download sales report result on the above to see how it works.</p>
<p><strong>4.2.2.3. <a name="4.2.2.3">XFCELL</a></strong><br />
This is a simple function to get variable&#8217;s cell name and return cell name or cell name string such as A12,A13,A14.</p>
<p>Format:<br />
%{=XFCELL(VAR)}</p>
<p>Example:<br />
%{=XFCELL(ITEM)}</p>
<p><strong>4.2.2.4. <a name="4.2.2.4">XFMATCH</a></strong><br />
XFMATCH is used to search some values from specified searching range, if matched, it returns the cell names or values.</p>
<p>Format:<br />
%{XFMATCH(SEARCH_VALUES,SEARCH_RANGE)<br />
%{XFMATCH(SEARCH_VALUES,SEARCH_RANGE, PARENT_HIERARCHY)<br />
SEARCH_VALUES:  the values to be searched. which  can be a variable, cell name such as AJ12 or AJ12:AK20, or constant string separated by comma such as &#8220;A,B,C&#8221;. This function searches value by some orders. Assume SEARCH_VALUES is specified as &#8220;A,B,C&#8221;, function will search A first, if found return the result, then B, then C.<br />
SEARCH_RANGE:  the search range which can be a variable, cell name, or any constant string.<br />
PARENT_HIERARCHY:  Specify from which template range to search, 1 is the parent, 2 is the parent&#8217;s parent template range.</p>
<p>Example:<br />
#{=CONCATENATE(XFOFFSET(XFMATCH(&#8220;◎,○,▲&#8221;, 本紙, 1), 0, 1), &#8220;=&#8221;, XFOFFSET(XFMATCH(&#8220;○,▲,△&#8221;, 本紙, 1), 0, 1), XFOFFSET(XFMATCH(&#8220;△&#8221;, 本紙, 1), 0, 1))}<br />
In the example of ColumnCloneRangeService, we used function as above to search the cell which has one of values  ◎,○,▲. You can see the function is used in Excel formula expression.</p>
<p><strong>4.2.2.5. <a name="4.2.2.5">XFOFFSET</a></strong><br />
Get cell name with the specified offset. This function is like excel formula function OFFSET.</p>
<p>Format:<br />
%{=XFOFFSET(VAR,ROW,COL,PARENT_HIERARCHY)}<br />
VAR:  variable to be searched, which is a template variable.<br />
ROW:  row offset number<br />
COL:  column offset number<br />
PARENT_HIERARCHY: Specify from which template range to search, 1 is the parent, 2 is the parent&#8217;s parent template range.</p>
<p>Example:<br />
#{=CONCATENATE(XFOFFSET(XFMATCH(&#8220;◎,○,▲&#8221;, 本紙, 1), 0, 1), &#8220;=&#8221;, XFOFFSET(XFMATCH(&#8220;○,▲,△&#8221;, 本紙, 1), 0, 1), XFOFFSET(XFMATCH(&#8220;△&#8221;, 本紙, 1), 0, 1))}</p>
<p><strong>4.3. <a name="4.3">How to create your service</a></strong><br />
ExcelTDF provides mechanism to create your own range service, cell service and function service. The three interfaces are used to let you create your service easily.  These interfaces are IExcelRangeService, IExcelCellService and IExcelFunctionService.</p>
<p><strong>4.3.1. <a name="4.3.1">How to create template range service, IExcelRangeService</a></strong><br />
See the example of MyRowRangeService which do the same works as RowRangeService.</p>
<p><strong>4.3.1.1. <a name="4.3.1.1">Create IExcelRangeService implementation class</a></strong><br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;
<span style="color: #0000ff;">using</span> log4net;
<span style="color: #0000ff;">using</span> JanaBiz.Common.Serialize;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml.Data;

<span style="color: #0000ff;">namespace</span> myservice
{
    <span style="color: #008000;">/// &lt;summary&gt;</span>
    <span style="color: #008000;">/// Process excel range defined by top row, and bottom row.</span>
    <span style="color: #008000;">/// Template variable are replaced by value in data model.</span>
    <span style="color: #008000;">/// This is simple range. worksheet root range is this type.</span>
    <span style="color: #008000;">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">MyRowRangeService</span> : ExcelRangeServiceBase, IExcelRangeService
    {
        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Logger</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">readonly</span> ILog logger = LogManager.GetLogger(<span style="color: #0000ff;">typeof</span>(MyRowRangeService));

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">///  constructor</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #0000ff;">public</span> MyRowRangeService()
            : <span style="color: #0000ff;">base</span>()
        {
        }

        <span style="color: #0000ff;">#region interface method</span>

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Parse specified worksheet using data provider</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;param name="sheetIndex"&gt;&lt;/param&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> Parse(<span style="color: #2b91af;">int</span> sheetIndex)
        {
            <span style="color: #008000;">//if no data, not processing </span>
            <span style="color: #0000ff;">if</span> (ExcelRange == <span style="color: #0000ff;">null</span> || ExcelRange.DataProvider == <span style="color: #0000ff;">null</span>) <span style="color: #0000ff;">return</span>;

            <span style="color: #008000;">//get data provider</span>
            IRangeDataProvider dataProvider = ExcelRange.DataProvider;

            <span style="color: #008000;">//reset mapping info</span>
            ExcelRange.DataMapping.Clear();

            <span style="color: #008000;">//get mapping info from data provider</span>
            SerializableDictionary&lt;<span style="color: #2b91af;">string</span>, ExcelAttribute&gt; dmp = dataProvider.GetMappingData(dataProvider[0]);
            ExcelRange.DataMapping.Add(dmp);

            <span style="color: #008000;">//set data values into mapped variables</span>
            SetNewCellValues(ExcelRange, dmp, ExcelRange.Top, ExcelRange.Bottom, 0, 0);

            <span style="color: #008000;">//no row or column index moved or changed</span>
            ExcelRange.ChangedRowCount = 0;

            <span style="color: #008000;">//process flag of this range</span>
            ExcelRange.Parsed = <span style="color: #0000ff;">true</span>;
        }

        <span style="color: #0000ff;">#endregion</span>

    }
}</pre>
</div>
<p><strong>4.3.1.2. <a name="4.3.1.2">Add your service object into configuration file</a></strong><br />
In your application configuration file, there is Spring.NET configuration section of object; add your object as following.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">  &lt;!-- my range service--&gt;
&lt;objects&gt;
&lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"<strong>MyRowRangeService</strong>"</span> type=<span style="color: #a31515;">"myservice.MyRowRangeService, Your_Assembly(dll)"</span>  singleton=<span style="color: #a31515;">"false"</span>/&gt;
&lt;/objects&gt;</pre>
</div>
<p><strong>4.3.1.3. <a name="4.3.1.3">Set your service into your template range configuration</a></strong></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">&lt;?xml version="1.0" encoding="shift_jis"?&gt;</span>
&lt;objects xmlns=<span style="color: #a31515;">"http://www.springframework.net"</span> &gt;
  <span style="color: #008000;">&lt;!-- sheet 1 --&gt;</span>
  &lt;object id=<span style="color: #a31515;">"MyRowRangeService_SHEET1"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"ROOT"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"Top"</span> value=<span style="color: #a31515;">"8"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"Bottom"</span> value=<span style="color: #a31515;">"10"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"RowRangeService"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ChildRanges"</span>&gt;
      &lt;list element-type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span>&gt;
        &lt;ref object=<span style="color: #a31515;">"MyRangeService"</span>/&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/object&gt;

  &lt;object id=<span style="color: #a31515;">"MyRangeService"</span> type=<span style="color: #a31515;">"JanaBiz.OpenXml.TemplateRange, JanaBiz.OpenXml"</span> singleton=<span style="color: #a31515;">"false"</span>&gt;
    &lt;property name=<span style="color: #a31515;">"RangeName"</span> value=<span style="color: #a31515;">"MYRANGE"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"LeftTop"</span> value=<span style="color: #a31515;">"L8"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"RightBottom"</span> value=<span style="color: #a31515;">"BE10"</span>/&gt;
    &lt;property name=<span style="color: #a31515;">"ServiceId"</span> value=<span style="color: #a31515;">"<strong>MyRowRangeService</strong>"</span>/&gt;
  &lt;/object&gt;
&lt;/objects&gt;</pre>
</div>
<p>That is all, now ExcelTDF will call your service of MyRowRangeService to process specified range in your template configuration file.</p>
<p><strong>4.3.2. <a name="4.3.2">How to create your custom cell service, IExcelCellService</a></strong><br />
See the example of MyVDListCellService which performs the same work as XSVDLIST</p>
<p><strong>4.3.2.1. <a name="4.3.2.1">Create implementation class of IExcelCellService</a></strong></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Collections;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;

<span style="color: #0000ff;">using</span> DocumentFormat.OpenXml;
<span style="color: #0000ff;">using</span> DocumentFormat.OpenXml.Packaging;
<span style="color: #0000ff;">using</span> DocumentFormat.OpenXml.Spreadsheet;
<span style="color: #0000ff;">using</span> log4net;

<span style="color: #0000ff;">using</span> JanaBiz.ExcelFormulaParser;

<span style="color: #0000ff;">namespace</span> myservice
{
    <span style="color: #008000;">/// &lt;summary&gt;</span>
    <span style="color: #008000;">/// My validate list cell service </span>
    <span style="color: #008000;">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">MyVDListCellService</span> : ExcelCellServiceBase, IExcelCellService
    {
        <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">readonly</span> ILog logger = LogManager.GetLogger(<span style="color: #0000ff;">typeof</span>(MyVDListCellService));

        <span style="color: #0000ff;">public</span> MyVDListCellService()
            : <span style="color: #0000ff;">base</span>()
        {
        }

        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> Parse(<span style="color: #2b91af;">int</span> sheetIndex)
        {
            <span style="color: #008000;">//1: get parameters</span>
            Parameters = GetExpressionParameters(ExprTreeNode, sheetIndex);

            <span style="color: #008000;">//2: check exists function variable in template </span>
            <span style="color: #0000ff;">if</span> (!ExcelRange.IsMyVariable(CellData.VarName))
            {
                <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ServiceException(<span style="color: #0000ff;">this</span>, <span style="color: #a31515;">"E_NO_VDLIST_VAR"</span>, CellData.VarName);
            }

            <span style="color: #008000;">//3: check if no paramter</span>
            <span style="color: #0000ff;">if</span> (Parameters.Count == 0)
            {
                <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ServiceException(<span style="color: #0000ff;">this</span>, <span style="color: #a31515;">"E_NO_PARAM"</span>);
            }

            <span style="color: #008000;">//4: check if parameter is empty</span>
            <span style="color: #2b91af;">string</span> listValues = Parameters[0].Param;
            <span style="color: #0000ff;">if</span> (<span style="color: #2b91af;">string</span>.IsNullOrEmpty(listValues))
            {
                <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ServiceException(<span style="color: #0000ff;">this</span>, <span style="color: #a31515;">"E_EMPTY_PARAM"</span>);
            }

            <span style="color: #008000;">//5: parameter type check</span>
            <span style="color: #0000ff;">switch</span> (Parameters[0].ParamType)
            {
                <span style="color: #008000;">//if it is variable</span>
                <span style="color: #0000ff;">case</span> ParamType.VARIABLE:
                    IList&lt;<span style="color: #2b91af;">string</span>&gt; cells = GetReferencesOfVariable(listValues, sheetIndex, ExcelRange, ListIndex);
                    <span style="color: #0000ff;">if</span> (cells == <span style="color: #0000ff;">null</span> || cells.Count == 0)
                    {
                        <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ServiceException(<span style="color: #0000ff;">this</span>, <span style="color: #a31515;">"E_VAR_NOT_FOUND"</span>, listValues);
                    }
                    <span style="color: #2b91af;">string</span>[] cellrefs = OpenXmlSpreadsheet.CreateMergeCellname(WorksheetPart, cells.ToArray());
                    <span style="color: #0000ff;">if</span> (cellrefs.Length &gt; 1)
                    {
                        listValues = <span style="color: #2b91af;">string</span>.Format(<span style="color: #a31515;">"{0}:{1}"</span>, cellrefs[0], cellrefs[1]);
                    }
                    <span style="color: #0000ff;">break</span>;
                <span style="color: #008000;">//if it is cell reference</span>
                <span style="color: #0000ff;">case</span> ParamType.CELL:
                <span style="color: #008000;">//if it is text </span>
                <span style="color: #0000ff;">case</span> ParamType.TEXT:
                    <span style="color: #0000ff;">break</span>;
            }

            <span style="color: #008000;">//do your work here </span>
            <span style="color: #008000;">//set data validate list formula1            </span>
            SetCellValue(CellData.DataType, CellData.CellName, CellData.CellValue);
            OpenXmlSpreadsheet.SetDataValidateFormula1(WorksheetPart, CellData.CellName, listValues);
        }
    }
}</pre>
</div>
<p><strong>4.3.2.2. <a name="4.3.2.2">Add your service object into configuration file</a></strong><br />
In your application configuration file, there is Spring.NET configuration section of object, add your object as following.</p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">  &lt;!-- my cell service--&gt;
&lt;objects&gt;
&lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"<strong>MYVDLIST</strong>"</span> type=<span style="color: #a31515;">"myservice.MyVDListCellService, Your_Assembly(dll)"</span>  singleton=<span style="color: #a31515;">"false"</span>/&gt;
&lt;/objects&gt;</pre>
</div>
<p>Now you can use MYVDLIST in your template. ExcelTDF will parse template and build your cell service MYVDLIST by calling your created class.</p>
<p><a href="/wp-content/uploads/2010/09/f-myvdlist.png"><img class="aligncenter size-full wp-image-512" title="f-myvdlist" src="/wp-content/uploads/2010/09/f-myvdlist.png" alt="" width="508" height="57" /></a></p>
<p><strong>4.3.3. <a name="4.3.3"> How to create your custom function service, IExcelFunctionService</a></strong><br />
Custom function service is the same as custom cell service except that function service must return a result. The result is set in property of FunctionResultValue. See the following example; it does the same work as the XFCELL function explained above.</p>
<p><strong>4.3.3.1. <a name="4.3.3.1"> Create your implementation class of IExcelFunctionService</a></strong></p>
<p><!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Collections;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Text;

<span style="color: #0000ff;">using</span> log4net;
<span style="color: #0000ff;">using</span> JanaBiz.OpenXml;

<span style="color: #0000ff;">namespace</span> myservice
{
    <span style="color: #008000;">/// &lt;summary&gt;</span>
    <span style="color: #008000;">/// Get variable's cell name </span>
    <span style="color: #008000;">/// %{=XFCELL(VAR)}</span>
    <span style="color: #008000;">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">MyCellFunctionService</span> : ExcelCellServiceBase, IExcelFunctionService
    {
        <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">readonly</span> ILog logger = LogManager.GetLogger(<span style="color: #0000ff;">typeof</span>(MyCellFunctionService));

        <span style="color: #0000ff;">public</span> MyCellFunctionService()
            : <span style="color: #0000ff;">base</span>()
        {
        }

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// do your work here </span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #008000;">/// &lt;param name="sheetIndex"&gt;&lt;/param&gt;</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> Parse(<span style="color: #2b91af;">int</span> sheetIndex)
        {
            Parameters = GetExpressionParameters(ExprTreeNode, sheetIndex);

            <span style="color: #008000;">//1: no parameter check</span>
            <span style="color: #0000ff;">if</span> (Parameters.Count == 0)
                <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ServiceException(<span style="color: #0000ff;">this</span>, <span style="color: #a31515;">"E_NO_PARAM"</span>);

            <span style="color: #008000;">//2: get cellname parameter</span>
            <span style="color: #2b91af;">string</span> var1 = Parameters[0].Param;

            <span style="color: #008000;">//3: empty parameter check</span>
            <span style="color: #0000ff;">if</span> (<span style="color: #2b91af;">string</span>.IsNullOrEmpty(var1))
                <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ServiceException(<span style="color: #0000ff;">this</span>, <span style="color: #a31515;">"E_EMPTY_PARAM"</span>);

            <span style="color: #008000;">//4: parameter type</span>
            <span style="color: #0000ff;">switch</span> (Parameters[0].ParamType)
            {
                <span style="color: #008000;">//it is a variable</span>
                <span style="color: #0000ff;">case</span> ParamType.VARIABLE:
                    FunctionResultValue = GetVariableResultAsString(
                        GetReferencesOfVariable(var1, sheetIndex, ExcelRange, ListIndex));
                    <span style="color: #0000ff;">break</span>;
                <span style="color: #008000;">//it is a cell name</span>
                <span style="color: #0000ff;">case</span> ParamType.CELL:
                    FunctionResultValue = var1;
                    <span style="color: #0000ff;">break</span>;
                <span style="color: #008000;">//for others</span>
                <span style="color: #0000ff;">default</span>:
                    <span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> ServiceException(<span style="color: #0000ff;">this</span>, <span style="color: #a31515;">"E_NOT_CELLNAME"</span>, var1);
            }
        }
    }
}</pre>
</div>
<p><strong>4.3.3.2. <a name="4.3.3.2">Add your service object into configuration file</a></strong><br />
In your application configuration file, there is Spring.NET configuration section of object, add your object as following.<br />
<!-- HTML generated using hilite.me --></p>
<div class="div-example">
<pre style="margin: 0; line-height: 125%;">  &lt;!-- my function service--&gt;
&lt;objects&gt;
&lt;<span style="color: #2b91af;">object</span> id=<span style="color: #a31515;">"<strong>MYCELL</strong>"</span> type=<span style="color: #a31515;">"myservice.MyCellFunctionService, Your_Assembly(dll)"</span>  singleton=<span style="color: #a31515;">"false"</span>/&gt;
&lt;/objects&gt;</pre>
</div>
<p>Now you can use MYCELL in your template. ExcelTDF will parse template and build your cell service MYCELL by calling your created class.</p>
<p><a href="/wp-content/uploads/2010/09/f-mycell.png"><img class="aligncenter size-full wp-image-517" title="f-mycell" src="/wp-content/uploads/2010/09/f-mycell.png" alt="" width="516" height="56" /></a><!--:--></p>
<p>The post <a href="http://www.janabiz.com/exceltdf/">ExcelTDF Package Introduction</a> appeared first on <a href="http://www.janabiz.com">ジャナ・ビジネス・コンサルティング</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.janabiz.com/exceltdf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

 Served from: www.janabiz.com @ 2026-05-02 03:59:05 by W3 Total Cache -->