---
# System prepended metadata

title: ReportX-ODF擴充

---

# ReportX-ODF擴充

**專案連結**:[ReportX](http://192.168.1.136/roychou/ReportX)
ReportX 擴充可以支援儲存.odf相關格式
ODF包含以下五種格式：
– .odt：對應Word(.doc .docx)
– .ods：對應Excel(.xls .xlsx)
– .odp：對應PowerPoint(.ppt .pptx)
– .odg：對應Visio
– .odb：對應Access

## ODT格式

參考文件-[OpenDocument technical specification](https://en.wikipedia.org/wiki/OpenDocument_technical_specification#Format_internals)
OpenDocument文件通常由包含許多文件和目錄的zip檔組成，可拆解為以下檔案

* XML
  * content.xml
  * meta.xml
  * style.xml
  * setting.xml
* 其他檔案
   * mimetype
* 資料夾
   * META-INF
      * manifest.xml
   * Thumbnails(縮圖)
      * thumbnail.png

以下為主要相關檔案的簡介
* content.xml
最重要的檔案，記錄文檔的實際內容，可單獨存在形成Odt。

* style.xml
記錄文件樣式以及格式，也有一部分樣式會在content.xml中，可結合進content成一個檔案。

* meta.xml
記錄文件數據，例如作者、最後修改者、日期。

* setting.xml 
記錄基本係數

## 組成Odt的檔案格式
參考文件-[OASIS OpenDocument](http://docs.oasis-open.org/office/v1.1/OS/OpenDocument-v1.1-html/OpenDocument-v1.1.html#14.1.1.Style%20Mappings|outline)
文件說明組成Odt的content.xml 格式

## 實驗
* doc 更改副檔名 odt: 不可行
* doc 更名成content.xml 壓縮成 odt: 不可行
* odt由xml組成，文字格式不合。

## Word 與 Odt檔的組合差異
Word 形成方法，以類似html語法所組成，形成檔案只需要寫入txt檔，更改附檔名成doc，即可完成，無須壓縮。
Odt  形成方法，採取XML的形式，有一套準則，去表明該如何組成其文件，完成檔案須命名為content.xml，並且需要進行壓縮，才可形成檔案。

**Word語法格式:**
```xml
<html xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:w="urn:schemas-microsoft-com:office:word"
xmlns:m="http://schemas.microsoft.com/office/2004/12/omml"
xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv=Content-Type content="text/html; charset=utf-8">
<meta name=ProgId content=Word.Document>
<meta name=Generator content="Microsoft Word 12 (filtered)">
<meta name=Originator content="Microsoft Word 12">
<title>知識統計表</title>
<!--[if gte mso 9]><xml>
<o:DocumentProperties>
<o:Subject>IQS Report</o:Subject>
<o:Author>IQS Technology Inc.</o:Author>
<o:Version>12.00</o:Version>
</o:DocumentProperties>
</xml><![endif]-->
<style>
<!--
@font-face
{font-family:新細明體;
panose-1:2 2 5 0 0 0 0 0 0 0;}
@font-face
{font-family:"Times New Roman";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Times New Roman;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:標楷體;
panose-1:3 0 5 9 0 0 0 0 0 0;}
@font-face
{font-family:"\@新細明體";
panose-1:2 2 5 0 0 0 0 0 0 0;}
@font-face
{font-family:"\@標楷體";
panose-1:3 0 5 9 0 0 0 0 0 0;}
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
margin-bottom:.0001pt;
font-size:9.0pt;
font-family:"Times New Roman","sans-serif";}
p.MsoHeader, li.MsoHeader, div.MsoHeader
{mso-style-link:"頁首 字元";
margin:0cm;
margin-bottom:.0001pt;
layout-grid-mode:char;
font-size:10.0pt;
font-family:"Times New Roman","sans-serif";}
p.MsoFooter, li.MsoFooter, div.MsoFooter
{mso-style-link:"頁尾 字元";
margin:0cm;
margin-bottom:.0001pt;
layout-grid-mode:char;
font-size:10.0pt;
font-family:"Times New Roman","sans-serif";}
span.a
{mso-style-name:"頁首 字元";
mso-style-link:頁首;}
span.a0
{mso-style-name:"頁尾 字元";
mso-style-link:頁尾;}
p
{padding:0cm 0cm 0cm 0cm;
margin:0cm 0.1cm 0cm 0.1cm;
}
td
{font-size:9.0pt;
font-family:新細明體;
padding:0cm 0cm 0cm 0cm;
}
.FmtDate
{mso-number-format:"yyyy\/ mm\/ dd\\ hh\:mm\:ss";}
@page Section1
{size:595.3pt 841.9pt;
font-size:9.0pt;
font-family:新細明體;
margin:2.0cm 2.0cm 2.0cm 2.0cm;}
div.Section1
{page:Section1;}
-->
</style>
</head>
<body lang=ZH-TW style='text-justify-trim:punctuation'>
<div class=Section1>
<p class=MsoNormal align=center style='text-align:center;font-size:18.0pt;font-family:標楷體;margin:0 0 8pt 0'>知識統計表</p>
<p style='text-align:center;font-size:14.0pt;font-family:"Times New Roman","serif";margin:0 0 4pt 0'>2019/07/01&nbsp;-&nbsp;2019/07/31&nbsp;</p>
<p class=MsoNormal align=right style='text-align:right;word-break:break-all;font-size:8.0pt;font-family:"Times New Roman","serif";margin:0 0 0 0'>製表人：brucechen<br />製表時間：2019/08/26 16:38:36</p>
<p style='text-align:left;font-size:12.0pt;font-family:"Times New Roman","serif";margin:0 0 4pt 0'>※ 新增知識 (共 7 筆)</p>
<div align=center>
<table class=MsoNormalTable border=1 cellspacing=0 cellpadding=0 width="100%" style='width:100.0%;border-collapse:collapse;border:none'>
<thead><tr>
<td width=45 style='width:33.75pt;background:#EAF1FD;padding:0cm 5.4pt 0cm 5.4pt'>編號</td>
<td width=132 style='width:99.25pt;background:#EAF1FD;padding:0cm 5.4pt 0cm 5.4pt'>知識目錄</td>
<td width=283 style='width:212.6pt;background:#EAF1FD;padding:0cm 5.4pt 0cm 5.4pt'>知識標題</td>
<td width=104 style='width:78.0pt;background:#EAF1FD;padding:0cm 5.4pt 0cm 5.4pt'>建立時間</td>
<td width=92 style='width:69.1pt;background:#EAF1FD;padding:0cm 5.4pt 0cm 5.4pt'>建立人員</td>
</tr></thead>
<td style='text-align:center'>7310</td>
<td style='text-align:left'>公司部門-公告文件區\品牌服務事業部BSBU\品牌經營服務處(2210)</td>
<td style='text-align:left'>2019年7月 Epson商品銷售活動及售價表通知</td>
<td style='text-align:center'>2019/07/01 10:06</td>
<td style='text-align:center'>鄭央辰&nbsp;</td>
</tr>
<td style='text-align:center'>7311</td>
<td style='text-align:left'>維修知識區\EPSON 愛普生\04-商用傳真複合機\WF-M5799_M5299\技術通報</td>
<td style='text-align:left'>WF-M5299_M5799_C5290_C5790_C579R 滾輪組異常</td>
<td style='text-align:center'>2019/07/11 13:47</td>
<td style='text-align:center'>蔡長生&nbsp;</td>
</tr>
<td style='text-align:center'>7312</td>
<td style='text-align:left'>公司規章辦法\規章總表</td>
<td style='text-align:left'>規章總表</td>
<td style='text-align:center'>2019/07/12 15:18</td>
<td style='text-align:center'>游淳茹&nbsp;</td>
</tr>
<td style='text-align:center'>7313</td>
<td style='text-align:left'>公司部門-公告文件區\品牌服務事業部BSBU\品牌經營服務處(2210)</td>
<td style='text-align:left'>2019 7月大圖新產品教育訓練講義</td>
<td style='text-align:center'>2019/07/15 10:32</td>
<td style='text-align:center'>鄭央辰&nbsp;</td>
</tr>
<td style='text-align:center'>7314</td>
<td style='text-align:left'>維修知識區\EPSON 愛普生\03-相片複合機\XP-4101\Driver or Firmware</td>
<td style='text-align:left'>XP-4101 韌體FWG510TL_MB13J6</td>
<td style='text-align:center'>2019/07/15 12:03</td>
<td style='text-align:center'>陳正雄&nbsp;</td>
</tr>
<td style='text-align:center'>7315</td>
<td style='text-align:left'>維修知識區\EPSON 愛普生\02-噴墨印表機\XP-15010\Driver or Firmware</td>
<td style='text-align:left'>XP-15010 韌體 -FWG150TL_NW01J7</td>
<td style='text-align:center'>2019/07/15 12:08</td>
<td style='text-align:center'>陳正雄&nbsp;</td>
</tr>
<td style='text-align:center'>7316</td>
<td style='text-align:left'>維修知識區\EPSON 愛普生\04-商用傳真複合機\WF-2831\Driver or Firmware</td>
<td style='text-align:left'>WF-2831 韌體 FWG511TL_AL13J6</td>
<td style='text-align:center'>2019/07/15 12:14</td>
<td style='text-align:center'>陳正雄&nbsp;</td>
</tr>
</table>
<p style='text-align:left;margin:0 0 0 0'>※編號前方若有「◎」，則表示該知識已失效。</p>
</div>
<br>
</div>
</body>
</html>

```

## S5 報表組成
### ODT檔案 xml 組成
為了不求產生多個檔案壓縮，所以只壓縮一個content.xml來形成odt檔

content.xml的基本架構
``` xml=
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<office:document-content xmlns:anim='urn:oasis:names:tc:opendocument:xmlns:animation:1.0' xmlns:chart='urn:oasis:names:tc:opendocument:xmlns:chart:1.0' xmlns:config='urn:oasis:names:tc:opendocument:xmlns:config:1.0' xmlns:db='urn:oasis:names:tc:opendocument:xmlns:database:1.0' xmlns:dc='http://purl.org/dc/elements/1.1/' xmlns:dr3d='urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0' xmlns:draw='urn:oasis:names:tc:opendocument:xmlns:drawing:1.0' xmlns:fo='urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0' xmlns:form='urn:oasis:names:tc:opendocument:xmlns:form:1.0' xmlns:grddl='http://www.w3.org/2003/g/data-view#' xmlns:math='http://www.w3.org/1998/Math/MathML' xmlns:meta='urn:oasis:names:tc:opendocument:xmlns:meta:1.0' xmlns:number='urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0' xmlns:office='urn:oasis:names:tc:opendocument:xmlns:office:1.0' xmlns:presentation='urn:oasis:names:tc:opendocument:xmlns:presentation:1.0' xmlns:script='urn:oasis:names:tc:opendocument:xmlns:script:1.0' xmlns:smil='urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0' xmlns:style='urn:oasis:names:tc:opendocument:xmlns:style:1.0' xmlns:svg='urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0' xmlns:table='urn:oasis:names:tc:opendocument:xmlns:table:1.0' xmlns:text='urn:oasis:names:tc:opendocument:xmlns:text:1.0' xmlns:xforms='http://www.w3.org/2002/xforms' xmlns:xhtml='http://www.w3.org/1999/xhtml' xmlns:xlink='http://www.w3.org/1999/xlink' office:version='1.2'>
```
接著會是字體的格式語法

``` xml =
<office:font-face-decls>
    <style:font-face style:name='Calibri' svg:font-family='Calibri' style:font-family-generic='swiss' style:font-pitch='variable' svg:panose-1='2 15 5 2 2 2 4 3 2 4'/>
    <style:font-face style:name='新細明體' svg:font-family='新細明體' style:font-family-generic='roman' style:font-pitch='variable' svg:panose-1='2 2 5 0 0 0 0 0 0 0'/>
    <style:font-face style:name='Times New Roman' svg:font-family='Times New Roman' style:font-family-generic='roman' style:font-pitch='variable' svg:panose-1='2 2 6 3 5 4 5 2 3 4'/>
    <style:font-face style:name='標楷體' svg:font-family='標楷體' style:font-family-generic='script' style:font-pitch='fixed' svg:panose-1='3 0 5 9 0 0 0 0 0 0'/>
    <style:font-face style:name='Calibri Light' svg:font-family='Calibri Light' style:font-family-generic='swiss' style:font-pitch='variable' svg:panose-1='2 15 3 2 2 2 4 3 2 4'/>
  </office:font-face-decls>
  ```
  再來則會是文件的樣式設定(類似於css)
  一開始的最外層
  ``` xml =
  <office:automatic-styles></office:automatic-styles>
  ```
以下是樣式的語法
不同屬性值代表設定文件的不同處之樣式屬性
例如:文字會用text、表格用table

* paragraph-properties 設定段落
* text-properties      設定文字
* table-properties      設定表格
* table-cell-properties 設定表格欄位
* table-column 設定欄
* table-row 設定列
* page-layout-properties 設定整個文件頁面(從style.xml轉移而來)



**完整樣式程式碼:**
``` xml
  <office:automatic-styles>
  <!--字體相關設定-->
    <style:style style:name='Title' style:parent-style-name='內文' style:master-page-name='MP0' style:family='paragraph'>
      <style:paragraph-properties fo:break-before='page' fo:text-align='center' fo:margin-bottom='0.1111in'/>
      <style:text-properties style:font-name='標楷體' style:font-name-asian='標楷體' fo:font-size='18pt' style:font-size-asian='18pt' style:font-size-complex='18pt'/>
    </style:style>
    <style:style style:name='User' style:parent-style-name='內文' style:family='paragraph'>
      <style:paragraph-properties style:line-break='normal' fo:text-align='end'/>
      <style:text-properties fo:font-size='8pt' style:font-size-asian='8pt' style:font-size-complex='8pt'/>
    </style:style>
    <!--表格 欄設定--> 
    <style:style style:name='TableColumn4' style:family='table-column'>
      <style:table-column-properties style:column-width='0.543in'/>
    </style:style>
    <style:style style:name='TableColumn5' style:family='table-column'>
      <style:table-column-properties style:column-width='4.2069in'/>
    </style:style>
    <style:style style:name='TableColumn6' style:family='table-column'>
      <style:table-column-properties style:column-width='0.968in'/>
    </style:style>
    <style:style style:name='TableColumn7' style:family='table-column'>
      <style:table-column-properties style:column-width='0.9638in'/>
    </style:style>
    <!--表格 本體相關設定-->
    <style:style style:name='Table' style:family='table'>
      <style:table-properties style:width='6.6819in' fo:margin-left='0in' table:align='center'/>
    </style:style>
    <style:style style:name='TitleTableRow' style:family='table-row'>
       <!--表格 列相關設定-->  
      <style:table-row-properties/>
    </style:style>
    <style:style style:name='TableCell' style:family='table-cell'>
     <!--表格 欄位相關設定-->   
      <style:table-cell-properties fo:border='0.0104in outset #000000' fo:background-color='#EAF1FD' style:writing-mode='lr-tb' style:vertical-align='middle' fo:padding-top='0in' fo:padding-left='0.075in' fo:padding-bottom='0in' fo:padding-right='0.075in'/>
    </style:style>
    <style:style style:name='ContentTableCell' style:family='table-cell'>
      <style:table-cell-properties fo:border='0.0104in outset #000000' fo:background-color='#EAF1FD' style:writing-mode='lr-tb' style:vertical-align='middle' fo:padding-top='0in' fo:padding-left='0in' fo:padding-bottom='0in' fo:padding-right='0in'/>
    </style:style>
    <style:style style:name='Data' style:parent-style-name='內文' style:family='paragraph'>
      <style:paragraph-properties fo:text-align='center'/>
      <style:text-properties style:font-name='新細明體' style:font-name-complex='新細明體'/>
    </style:style>
    <style:style style:name='SequenceDataTableCell' style:family='table-cell'>
      <style:table-cell-properties fo:border='0.0104in outset #000000' style:writing-mode='lr-tb' style:vertical-align='middle' fo:padding-top='0in' fo:padding-left='0in' fo:padding-bottom='0in' fo:padding-right='0in'/>
    </style:style>
    <style:style style:name='ContentDataTableCell' style:family='table-cell'>
      <style:table-cell-properties fo:border='0.0104in outset #000000' style:writing-mode='lr-tb' style:vertical-align='middle' fo:padding-top='0in' fo:padding-left='0.0416in' fo:padding-bottom='0in' fo:padding-right='0in'/>
    </style:style>
    <style:style style:name='KnowledgeDataTableCell' style:family='table-cell'>
      <style:table-cell-properties fo:border='0.0104in outset #000000' style:writing-mode='lr-tb' style:vertical-align='middle' fo:padding-top='0in' fo:padding-left='0in' fo:padding-bottom='0in' fo:padding-right='0.0416in'/>
    </style:style>
    <style:style style:name='KnowledgeData' style:parent-style-name='內文' style:family='paragraph'>
      <style:paragraph-properties fo:text-align='end' fo:margin-right='0.1666in'/>
      <style:text-properties style:font-name='新細明體' style:font-name-complex='新細明體'/>
    </style:style>
    <style:style style:name='MarkContentData' style:parent-style-name='內文' style:family='paragraph'>
      <style:text-properties style:font-name='新細明體' style:font-name-complex='新細明體' fo:color='#FF0000'/>
    </style:style>
    <style:style style:name='ContentData' style:parent-style-name='內文' style:family='paragraph'>
      <style:text-properties style:font-name='新細明體' style:font-name-complex='新細明體'/>
    </style:style>
    <!-- style.xml 設定 -->
<!-- 此段放在 <office:automatic-styles>內-->
    <style:page-layout style:name='PL0'>
      <style:page-layout-properties fo:page-width='8.268in' fo:page-height='11.693in' style:print-orientation='portrait' fo:margin-top='0.7875in' fo:margin-left='0.7875in' fo:margin-bottom='0.7875in' fo:margin-right='0.7875in' style:num-format='1' style:writing-mode='lr-tb'>
        <style:footnote-sep style:width='0.007in' style:rel-width='33%' style:color='#000000' style:line-style='solid' style:adjustment='left'/>
      </style:page-layout-properties>
    </style:page-layout>
  </office:automatic-styles>
  <!-- 此段放在 <office:automatic-styles>外-->
  <office:master-styles>
    <style:master-page style:name='MP0' style:page-layout-name='PL0'/>
  </office:master-styles>
```
接著是資料主體

``` xml
  <office:body>
    <office:text text:use-soft-page-breaks='true'>
    <!-- 文字段落 -->
      <text:p text:style-name='Title'>知識數量統計表</text:p>
      <text:p text:style-name='User'>
        製表人：林家弘<text:line-break/>製表時間：2019/09/03 05:52:04
      </text:p>
      <!-- 表格 -->
      <table:table table:style-name='Table'>
      <!-- 表格欄 -->
        <table:table-columns>
          <table:table-column table:style-name='TableColumn4'/>
          <table:table-column table:style-name='TableColumn5'/>
          <table:table-column table:style-name='TableColumn6'/>
          <table:table-column table:style-name='TableColumn7'/>
        </table:table-columns>
        <!-- 表格列 -->
        <table:table-row table:style-name='TitleTableRow '>
        <!-- 表格欄位 -->
          <table:table-cell  table:style-name='TableCell'>
            <text:p text:style-name="Data" >順序</text:p>
          </table:table-cell>
          <table:table-cell  table:style-name='TableCell'>
            <text:p text:style-name="Data" >知識目錄</text:p>
          </table:table-cell>
          <table:table-cell  table:style-name='TableCell'>
            <text:p text:style-name="Data" >有效知識</text:p>
          </table:table-cell>
          <table:table-cell  table:style-name='TableCell'>
            <text:p text:style-name="Data" >無效知識</text:p>
          </table:table-cell>
        </table:table-row>
        <table:table-row table:style-name='TitleTableRow '>
          <table:table-cell  table:style-name='SequenceDataTableCell'>
            <text:p text:style-name="Data" >1</text:p>
          </table:table-cell>
          <table:table-cell  table:style-name='ContentDataTableCell'>
            <text:p text:style-name="MarkContentData" >◎目錄0</text:p>
          </table:table-cell>
          <table:table-cell  table:style-name='KnowledgeDataTableCell'>
            <text:p text:style-name="KnowledgeData" >8</text:p>
          </table:table-cell>
          <table:table-cell  table:style-name='KnowledgeDataTableCell'>
            <text:p text:style-name="KnowledgeData" >4</text:p>
          </table:table-cell>
        </table:table-row>
        <table:table-row table:style-name='TitleTableRow '>
          <!-- table:number-columns-spanned 合併欄位 2代表 2格 -->
          <table:table-cell  table:style-name='ContentTableCell' table:number-columns-spanned="2" >
            <text:p text:style-name="Data" >合計</text:p>
          </table:table-cell>
          <!--table:covered-table-cell 用來填補空缺 若有spanned 則可以不必寫 -->
          <table:covered-table-cell/>
          <table:table-cell  table:style-name='ContentTableCell'>
            <text:p text:style-name='KnowledgeData'>8</text:p>
          </table:table-cell>
          <table:table-cell  table:style-name='ContentTableCell'>
            <text:p text:style-name='KnowledgeData'>4</text:p>
          </table:table-cell>
        </table:table-row>
      </table:table>
      <text:p text:style-name='ContentData'/>
    </office:text>
  </office:body>
</office:document-content>
```
以上組成一個xml，即可將檔案壓縮成odt的格式。

表格組成注意事項
``<table:table-columns>``代表欄，
裡面有幾個 ``<table:table-column/>``
 也要有幾個``<table:table-cell></table:table-cell>``
那如果要合併欄位 可用 
``<table:table-cell  table:number-columns-spanned="2">`` 來做橫向的合併欄位
若是想要垂直合併欄位，則是 `` <table:covered-table-cell/>``
**以下範例:**
```xml
      <!--這裡有12個column -->   
        <table:table-columns>
          <table:table-column table:style-name='TableColumn5'/>
          <table:table-column table:style-name='TableColumn6'/>
          <table:table-column table:style-name='TableColumn7'/>
          <table:table-column table:style-name='TableColumn8'/>
          <table:table-column table:style-name='TableColumn9'/>
          <table:table-column table:style-name='TableColumn10'/>
          <table:table-column table:style-name='TableColumn11'/>
          <table:table-column table:style-name='TableColumn12'/>
          <table:table-column table:style-name='TableColumn13'/>
          <table:table-column table:style-name='TableColumn14'/>
          <table:table-column table:style-name='TableColumn15'/>
          <table:table-column table:style-name='TableColumn16'/>
        </table:table-columns>
    <!-- 照理而言要有12個table-cell 但是 他每個cell都有rows-spanned 總和加起來是12這樣也不會使表格出錯-->
        <table:table-row table:style-name='TableRow '>
          <table:table-cell  table:style-name='HeaderTableCell' table:number-rows-spanned='2'>
            <text:p text:style-name="CenterWord" >順序</text:p>
          </table:table-cell>
          <table:table-cell  table:style-name='HeaderTableCell' table:number-rows-spanned='2'>
            <text:p text:style-name="CenterWord" >審核起始日</text:p>
          </table:table-cell>
          <table:table-cell  table:style-name='HeaderTableCell' table:number-columns-spanned='3'>
            <text:p text:style-name="CenterWord" >新增知識</text:p>
          </table:table-cell>
          <table:table-cell  table:style-name='HeaderTableCell' table:number-columns-spanned='3'>
            <text:p text:style-name="CenterWord" >修改知識</text:p>
          </table:table-cell>
          <table:table-cell  table:style-name='HeaderTableCell' table:number-columns-spanned='3'>
            <text:p text:style-name="CenterWord" >刪除知識</text:p>
          </table:table-cell>
          <table:table-cell  table:style-name='HeaderTableCell' table:number-rows-spanned='2'>
            <text:p text:style-name="CenterWord" >合計</text:p>
          </table:table-cell>
        </table:table-row>

        <table:table-row table:style-name='TableRow '>
        <!--這裡 <table:covered-table-cell/> 用了三組 + 九組<table:table-cell>-->
          <table:covered-table-cell/>
          <table:covered-table-cell/>
          <table:table-cell  table:style-name='HeaderTableCell'>
            <text:p text:style-name="CenterWord" >審核中</text:p>
          </table:table-cell>
          <table:table-cell  table:style-name='FooterTableCell'>
            <text:p text:style-name="CenterWord" >生效</text:p>
          </table:table-cell>
          <table:table-cell  table:style-name='HeaderTableCell'>
            <text:p text:style-name="CenterWord" >退件</text:p>
          </table:table-cell>
          <table:table-cell  table:style-name='HeaderTableCell'>
            <text:p text:style-name="CenterWord" >審核中</text:p>
          </table:table-cell>
          <table:table-cell  table:style-name='FooterTableCell'>
            <text:p text:style-name="CenterWord" >生效</text:p>
          </table:table-cell>
          <table:table-cell  table:style-name='HeaderTableCell'>
            <text:p text:style-name="CenterWord" >退件</text:p>
          </table:table-cell>
          <table:table-cell  table:style-name='HeaderTableCell'>
            <text:p text:style-name="CenterWord" >審核中</text:p>
          </table:table-cell>
          <table:table-cell  table:style-name='FooterTableCell'>
            <text:p text:style-name="CenterWord" >生效</text:p>
          </table:table-cell>
          <table:table-cell  table:style-name='HeaderTableCell'>
            <text:p text:style-name="CenterWord" >退件</text:p>
          </table:table-cell>
          <table:covered-table-cell/>
        </table:table-row>
```
形成的表格如下圖:
![](https://i.imgur.com/Z7a6Tox.jpg)
### Amount
產生Amount報表 odt 流程

``` csharp=
        public void AmountReportTest()
        {
            //生成假資料
            Random r = new Random();
            ModelKnowledgeAmount[] data = new ModelKnowledgeAmount[1];
            for (int i = 1 - 1; i >= 0; i--)
            {
                int num = r.Next(0, 30);
                int numw = r.Next(0, 5);
                string knowledge = "";
                string s = Guid.NewGuid().ToString("N");
                if (num % 2 == 0)
                {
                    knowledge = "◎目錄" + i;
                }
                else
                {
                    knowledge = "目錄" + i;
                }
                ModelKnowledgeAmount tmp = new ModelKnowledgeAmount
                {
                    sequence = i + 1,
                    knowledge = knowledge,
                    correctAmount = num,
                    wrongAmount = numw,

                };
                data[i] = tmp;
            }
         
            var datetime = DateTime.Now.ToString("yyyyMMddhhmmss");
            string[] cols = new string[4];
            cols[0] = "順序";
            cols[1] = "知識目錄";
            cols[2] = "有效知識";
            cols[3] = "無效知識";
            string title = "知識數量統計表";
            //組成xml資料
            Report Rpt = new Report();
            Amount AmountRes = Rpt.AmountReport(data, cols, title, DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss"), "林家弘", true);
            string res = AmountRes.render();
            //產生xml
            if (File.Exists("content.xml"))
                File.Delete("content.xml");
            File.AppendAllText("content.xml", res); // 檔案存在 路徑: D:\CSharp\ReportX\ReportXTests2\bin\Debug
            Assert.IsNotNull(res);
            //壓縮xml 產生odt
            if (File.Exists("content.xml"))
            {
                string inputFile = @"content.xml";
                string outputFile = @"./Amount(" + datetime + ").odt";
                byte[] buffer = new byte[4096];
                using (var output = new FileStream(outputFile, FileMode.Create, FileAccess.Write))
                using (var input = new FileStream(inputFile, FileMode.Open, FileAccess.Read))
                using (var zip = new ZipOutputStream(output))
                {
                    ZipEntry entry = new ZipEntry(inputFile);
                    entry.DateTime = DateTime.Now;
                    zip.PutNextEntry(entry);
                    int readLength;
                    do
                    {
                        readLength = input.Read(buffer, 0, buffer.Length);
                        if (readLength > 0)
                        {
                            zip.Write(buffer, 0, readLength);
                        }
                    } while (readLength > 0);
                }
            }
        }
```
從組成xml 開始
AmountReport
這裡主要進行的是產生content.xml資料主體的


``` csharp=
 public AmountReport AmountReport<T>(T[] data, string[] cols, string title,string dateTime,  string Creator, bool end = false)
        {
            AmountReport file = new AmountReport(typeof(T));
            if (cols.Length > 0)
            {
                file.setcut(cols);
            }

            file.setTile(title);
            file.setCreator(Creator);
            file.setCreatedDate(dateTime);
            file.setColumn();
            file.setData(data);

            if (end) //如果要顯示結算筆數 end =true;
            {
                file.setsum(data);
            }
            return file;
        }

```
逐條來解釋其作用
首先宣告AmountReport物件，執行時，也順便將客製化的樣式做了設定，

``` csharp=
    string customCSS = @"客製化樣式資料，由於基於排版，這裡的內容可參考上面的完整樣式程式碼";
        public AmountReport(Type model) : base(model)
        {
            setCustomStyle(customCSS);
        }
```
 傳入欲顯示的欄位
 setcut(cols)
``` csharp=
//amountreport:amount
        public void setcut(string[] cut)
        {
            changecut(cut);
        }
```
將顯示的標題欄位塞進陣列中
 ``` csharp=
 //amount
        public void changecut(string[] cut)
        {
            newcols = cut;
            var intersectResult = oldcols.Intersect(newcols);
            cols = intersectResult.ToArray();
            amount.colNum = cols.Length;
        }

```
接著設定表格名稱、製表時間、製表人

``` csharp=
//amountreport:amount
        public void setTile(string title)
        {
            setTitle(sheetName: title);
        }

        public void setCreator(string creator)
        {
            setTitle(author: creator);
        }

        public void setCreatedDate(string dateTime)
        {
            setTitle(dateTime: dateTime);
        }
```
帶入AmountModel中，之後進行組合
``` csharp=
 //amount
        public void setTitle(string author = null, string company = null, string sheetName = null, string dateTime = null)
        {
            if (author != null) amount.author = author;
            if (company != null) amount.company = company;
            if (sheetName != null) amount.sheetName = sheetName;
            if (dateTime != null) amount.datetime = dateTime;
        }
```
然後設定欄位
``` csharp=
//amountreport:amount
        public void setColumn()
        {
            ModelTR col = appendRow(cols);
            foreach (ModelTD td in col.tds)
                td.className = "column";
        }
```
appendRow 開始製作表格的每一列資料
判斷 value是否為null
若是null 則為欄位標題，不是則依序抓取資料再判定是否存在並加入

``` csharp=
 //amount
        public ModelTR appendRow(params object[] data)
        {
            ModelTR tr = new ModelTR();
            tr.tds = new List<ModelTD>();
            foreach (object cell in data)
            {

                ModelTD td = new ModelTD();
                var value = cell.GetType().GetProperty("value");

                if (value == null)
                {
                    td.data = cell.ToString();
                }
                else
                {
                    var colspan = cell.GetType().GetProperty("colspan");
                    var rowspan = cell.GetType().GetProperty("rowspan");
                    var fontSize = cell.GetType().GetProperty("fontSize");
                    var align = cell.GetType().GetProperty("align");
                    var bold = cell.GetType().GetProperty("bold");
                    var style = cell.GetType().GetProperty("style");
                    var className = cell.GetType().GetProperty("className");


                    if (value != null) td.data = value.GetValue(cell, null);
                    if (colspan != null) td.colspan = (int)colspan.GetValue(cell, null);
                    if (rowspan != null) td.rowspan = (int)rowspan.GetValue(cell, null);
                    if (fontSize != null) td.fontSize = fontSize.GetValue(cell, null).ToString();
                    if (align != null) td.align = align.GetValue(cell, null).ToString();
                    if (bold != null) td.bold = true;
                    if (style != null) td.style = style.GetValue(cell, null).ToString();
                    if (className != null) td.className = className.GetValue(cell, null).ToString();

                }
                tr.tds.Add(td);
            }
            trs.Add(tr);
            return tr;
        }
```
最後，加入表格內資料
``` csharp=
//amountreport:amount
        public void setData<T>(T[] data)
        {
            appendTable(data);
        }
```
appendTable 先取出屬性，對應欄位名稱，排序且塞入資料。

``` csharp=
 //amount
        public void appendTable<T>(T[] data, string trStyle = null, string className = null)
        {

            foreach (T tuple in data)
            {
                ModelTD[] tds = new ModelTD[cols.Length];
                ModelTR tr = new ModelTR();
                tr.tds = new List<ModelTD>();
                tr.style = trStyle;
                tr.className = className;
                foreach (var prop in tuple.GetType().GetProperties())
                {
                    try
                    {
                        Present attr = prop.GetCustomAttribute<Present>();
                        if (attr == null) continue;
                        int colinx = Array.IndexOf(cols, attr.getName());
                        object value = prop.GetValue(tuple, null);
                        tds[colinx] = new ModelTD()
                        {
                            col = attr.getName(),
                            data = value
                        };
                    }
                    catch (Exception)
                    {
                        continue;
                    }
                }
                foreach (ModelTD td in tds)
                    tr.tds.Add(td);
                trs.Add(tr);
            }
        }
```
如果還有總結，需記得AmountReport 帶入的參數中，end要為true
有牽扯到資料的總和的話會先在此算出，接著透過appendRow新增資料(appendRow上面已提過)
``` csharp=
//amountreport:amount
public void setsum<T>(T[] data) //總筆數
        {
            int sum_correct = 0;
            int sum_wrong = 0;
            string lastRowStyle = "TotalCell"; //預設CSS
            string lastClassName = "Data";
            foreach (T item in data)
            {
                foreach (var prop in item.GetType().GetProperties())
                {
                    switch (prop.Name)
                    {
                        case "correctAmount":
                            sum_correct += (int)prop.GetValue(item, null);
                            break;
                        case "wrongAmount":
                            sum_wrong += (int)prop.GetValue(item, null);
                            break;
                        default:
                            break;
                    }
                }
            }
            appendRow(new { colspan = getColCount() - 2, style = lastRowStyle, className = lastClassName, value = "合計" },
                new {   value = sum_correct,  className = lastClassName },
                new {   value = sum_wrong,  className = lastClassName });//統計資料數

        }
```
當所有資料都設置完後，再來就是將這些資料組合成xml
 string res = AmountRes.render();
``` csharp=
//amount
        public string render(int? width = null)
        {
            amount.body = new ViewBodyAmount(trs, width);
            ViewAmount report = new ViewAmount(amount);
            return report.render();
        }
```
設定amount.body的值，將用來組成
```csharp=
        public ViewBodyAmount(List<ModelTR> model, int? width = null)
        {
            this.model = model;
            this.width = width;
        }
```

  ViewAmount report = new ViewAmount(amount);
 將各段的xml語法集合成字串，將匯入content.xml
``` csharp=
  public class ViewAmount
    {
        private ModelAmount m;

        public ViewAmount(ModelAmount model)
        {
            m = model;
        }
        public string render()
        {
            string style = m.style.render(),
                   body = m.body.render();


            return string.Format(template, m.author, m.company, m.sheetName,m.datetime, style, body);

        }
        string template =
 @"<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<office:document-content xmlns:anim='urn:oasis:names:tc:opendocument:xmlns:animation:1.0' xmlns:chart='urn:oasis:names:tc:opendocument:xmlns:chart:1.0' xmlns:config='urn:oasis:names:tc:opendocument:xmlns:config:1.0' xmlns:db='urn:oasis:names:tc:opendocument:xmlns:database:1.0' xmlns:dc='http://purl.org/dc/elements/1.1/' xmlns:dr3d='urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0' xmlns:draw='urn:oasis:names:tc:opendocument:xmlns:drawing:1.0' xmlns:fo='urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0' xmlns:form='urn:oasis:names:tc:opendocument:xmlns:form:1.0' xmlns:grddl='http://www.w3.org/2003/g/data-view#' xmlns:math='http://www.w3.org/1998/Math/MathML' xmlns:meta='urn:oasis:names:tc:opendocument:xmlns:meta:1.0' xmlns:number='urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0' xmlns:office='urn:oasis:names:tc:opendocument:xmlns:office:1.0' xmlns:presentation='urn:oasis:names:tc:opendocument:xmlns:presentation:1.0' xmlns:script='urn:oasis:names:tc:opendocument:xmlns:script:1.0' xmlns:smil='urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0' xmlns:style='urn:oasis:names:tc:opendocument:xmlns:style:1.0' xmlns:svg='urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0' xmlns:table='urn:oasis:names:tc:opendocument:xmlns:table:1.0' xmlns:text='urn:oasis:names:tc:opendocument:xmlns:text:1.0' xmlns:xforms='http://www.w3.org/2002/xforms' xmlns:xhtml='http://www.w3.org/1999/xhtml' xmlns:xlink='http://www.w3.org/1999/xlink' office:version='1.2'>

 {4}
  <office:body>
    <office:text text:use-soft-page-breaks='true'>
      <text:p text:style-name='Title'>{2}</text:p>
      <text:p text:style-name='User'>
        製表人：{0}<text:line-break/>製表時間：{3}
      </text:p>
      <table:table table:style-name='Table'>
        <table:table-columns>
          <table:table-column table:style-name='TableColumn4'/>
          <table:table-column table:style-name='TableColumn5'/>
          <table:table-column table:style-name='TableColumn6'/>
          <table:table-column table:style-name='TableColumn7'/>
        </table:table-columns>
     {5}
      </table:table>
      <text:p text:style-name='ContentData'/>
    </office:text>
  </office:body>
</office:document-content>";
    }
```

` style = m.style.render()` 組成樣式主體
` body = m.body.render();` 組成資料主體


``` csharp=
//body.render
public class ViewBodyAmount
    {
        private List<ModelTR> model;
        public MemberInfo[] modeli;
        private int? width; // if not set, keep it is auto
        public ViewBodyAmount(List<ModelTR> model, int? width = null)
        {
            this.model = model;
            this.width = width;
        }
        //body = m.body.render();
        public string render()
        {
            string table_width = width == null ? "" : string.Format("width={0}", width),
                   trs = "";
            foreach (ModelTR tr in model)
            {
                string tr_className = tr.className == null ? "" : string.Format("class=\"{0}\" ", tr.className),
                       tr_customStyle = tr.style ?? "",
                       tr_style = string.Format("style=\"{0}\" ", tr_customStyle) + tr_className,
                       tds = ""
                      ;

                if (tr.tds != null)
                {
                    foreach (ModelTD td in tr.tds)
                    {
                        if (td == null) continue;
                        string attributes = "",
                               text_style = "",
                               td_style = "",
                               table_cell = "",
                               className = td.className == null ? "" : td.className,
                               data = td.data == null ? "" : td.data.ToString();

                        if (td.className == "column")
                        {
                            attributes += string.Format("table:style-name='TableCell'");
                            className = "Data";
                        }
                        if (td.className == null)
                        {
                            switch (td.col)
                            {
                                case "順序":
                                    attributes += string.Format("table:style-name='SequenceDataTableCell'");
                                    className = "Data";
                                    break;
                                case "知識目錄":
                                    attributes += string.Format("table:style-name='ContentDataTableCell'");
                                    className = "ContentData";
                                    var test = td.data.ToString().Substring(0, 1);
                                    if (test == "◎")
                                    {
                                        className = "MarkContentData";
                                    }
                                    else
                                    {
                                        className = "ContentData";
                                    }
                                    break;
                                case "有效知識":
                                    attributes += string.Format("table:style-name='KnowledgeDataTableCell'");
                                    className = "KnowledgeData";
                                    break;
                                case "無效知識":
                                    attributes += string.Format("table:style-name='KnowledgeDataTableCell'");
                                    className = "KnowledgeData";
                                    break;
                                default:
                                    attributes += string.Format("table:style-name='SequenceDataTableCell'");
                                    className = "Data";
                                    break;
                            }
                        }
                        if (td.className == "Data")
                        {
                            if (td.style != null)
                            {
                                attributes += string.Format("table:style-name='ContentTableCell' table:number-columns-spanned='2' ");
                                for (int i = 1; i < td.colspan; i++)
                                {
                                    table_cell += "<table:covere-table-cell/>";
                                }
                                className = "Data";
                            }
                            else
                            {
                                attributes += string.Format("table:style-name='ContentTableCell'");
                                className = "KnowledgeData";
                            }
                        }
                        if (td_style == null)
                            attributes += string.Format("table:style-name=\"{0}\" ", td_style);
                        text_style += string.Format("text:style-name=\"{0}\" ", className);
                        tds += string.Format(template_td, attributes, text_style, data, table_cell);
                    }
                }
                trs += string.Format(template_tr, tr_style, tds);
            }

            return string.Format(template, trs, table_width);
        }


        string template = @"{0}";
        string template_td = "<table:table-cell  {0}><text:p {1}>{2}</text:p></table:table-cell>{3} ";
        string template_tr = "<table:table-row table:style-name='TitleTableRow '>{1}</table:table-row>";
    }
```
patchCSS用來寫入字體相關樣式
costomCSS為客製樣式，在宣告物件時就已經將數值帶入

```csharp=
//style.render
  public class ViewStyleAmount
    {
        private string costomCSS = "";
        private string patchCSS = "";

        public ViewStyleAmount()
        {
            patchCSS = @"  <office:font-face-decls>
    <style:font-face style:name='Calibri' svg:font-family='Calibri' style:font-family-generic='swiss' style:font-pitch='variable' svg:panose-1='2 15 5 2 2 2 4 3 2 4'/>
    <style:font-face style:name='新細明體' svg:font-family='新細明體' style:font-family-generic='roman' style:font-pitch='variable' svg:panose-1='2 2 5 0 0 0 0 0 0 0'/>
    <style:font-face style:name='Times New Roman' svg:font-family='Times New Roman' style:font-family-generic='roman' style:font-pitch='variable' svg:panose-1='2 2 6 3 5 4 5 2 3 4'/>
    <style:font-face style:name='標楷體' svg:font-family='標楷體' style:font-family-generic='script' style:font-pitch='fixed' svg:panose-1='3 0 5 9 0 0 0 0 0 0'/>
    <style:font-face style:name='Calibri Light' svg:font-family='Calibri Light' style:font-family-generic='swiss' style:font-pitch='variable' svg:panose-1='2 15 3 2 2 2 4 3 2 4'/>
  </office:font-face-decls>";
        }

        public void setCustomCSS(string costomCSS)
        {
            this.costomCSS = costomCSS;
        }




        public string render()
        {
            string format_all_css = string.Format(global_css, patchCSS, costomCSS);
            return string.Format(template, format_all_css);
        }

        string template = @"{0}";

        string global_css = @"
            {0}
            {1}
        ";

    }
```
最後，形成content.xml，再壓縮即完成odt檔。
```csharp=
File.AppendAllText("content.xml", res);
```
### KBStatic 報表生成
大致上流程與Amount報表組成差不多，這個報表多了要顯示時間區間
這兩個參數帶入產出報表當月的前一個月的起始日
**beforeMouthOneDay 
beforeMouthLastDay**
```csharp=
 KBStatic KBSRes = Rpt.KBStaticReport(data, cols, title, DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss"), 
 beforeMouthOneDay, beforeMouthLastDay, "林家弘");
```
```csharp=
file.setCreatedDayRange(firstday, lastdday);
```
```csharp=
public void setCreatedDayRange(string firstday,string lastday)
{
     setTitle(dateRange: firstday+" - "+lastday);
}
```
```csharp=
public void setTitle(string author = null, string company = null, string sheetName = null, string dateTime = null, string dateRange = null)
 {
     if (author != null) kbs.author = author;
     if (company != null) kbs.company = company;
     if (sheetName != null) kbs.sheetName = sheetName;
     if (dateTime != null) kbs.datetime = dateTime;
     if (dateRange != null) kbs.dateRange = dateRange;
 }
```
並且這個報表沒有帶入end參數，並沒有總和。
### SignStatus 報表生成
這個報表有合併欄位
![](https://i.imgur.com/Z7a6Tox.jpg)
目前想到的解決方法，列出所要產生的各個欄位，分列去形成。
```csharp=
 string[] cols = new string[15];
            cols[0] = "順序";
            cols[1] = "審核起始日";
            cols[2] = "新增知識";
            cols[3] = "修改知識";
            cols[4] = "刪除知識";
            cols[5] = "合計";
            cols[6] = "新增知識審核";
            cols[7] = "新增知識生效";
            cols[8] = "新增知識退件";
            cols[9] = "修改知識審核";
            cols[10] = "修改知識生效";
            cols[11] = "修改知識退件";
            cols[12] = "刪除知識審核";
            cols[13] = "刪除知識生效";
            cols[14] = "刪除知識退件";

            string title = "知識統計表";
            Report Rpt = new Report();
            SignStatus SSRes = Rpt.SignStatusReport(data, cols, title, DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss"), beforeMouthOneDay, beforeMouthLastDay, "林家弘", true);
```

setColumn()
setSecondColun()
去形成兩排的表頭欄位
```csharp=
public SignStatusReport SignStatusReport<T>(T[] data, string[] cols, string title, string dateTime, string firstday, string lastdday, string Creator, bool end = false)
        {
            SignStatusReport file = new SignStatusReport(typeof(T));
            if (cols.Length > 0)
            {
                file.setcut(cols);
            }

            file.setTile(title);
            file.setCreator(Creator);
            file.setCreatedDate(dateTime);
            file.setCreatedDayRange(firstday, lastdday);
            file.setColumn();
            file.setSecondColumn();
            file.setData(data); ;

            if (end) //如果要顯示結算筆數 end =true;
            {
                file.setsum(data);
            }
            return file;
        }

```
setColumn()
給予className="column"
```csharp=
        public void setColumn()
        {
            ModelTR col = appendRow(cols);
            foreach (ModelTD td in col.tds)
                td.className = "column";
        }
```
setSecondColumn()
給予className="secondColumn"
```csharp=
        public void setSecondColumn()
        {
            ModelTR col = appendRow(cols);
            foreach (ModelTD td in col.tds)
                td.className = "secondColumn";
        }
```
在後面組成時
再去判斷組成欄位
```csharp=
//ViewBodySignStatus
 
                        if (td.className == "column")
                        {
                            switch (td.data)
                            {
                                case "順序":
                                    attributes += string.Format("table:style-name='HeaderTableCell' table:number-rows-spanned='2'");
                                    
                                    className = "CenterWord";
                                    break;
                                case "審核起始日":
                                    attributes += string.Format("table:style-name='HeaderTableCell' table:number-rows-spanned='2'");
                                    className = "CenterWord";
                                    break;
                                case "新增知識":
                                    attributes += string.Format("table:style-name='HeaderTableCell' table:number-columns-spanned='3'");
                                    className = "CenterWord";
                                    table_cell += "<table:covered-table-cell/>";
                                    table_cell += "<table:covered-table-cell/>";
                                    break;
                                case "修改知識":
                                    attributes += string.Format("table:style-name='HeaderTableCell' table:number-columns-spanned='3'");
                                    className = "CenterWord";
                                    table_cell += "<table:covered-table-cell/>";
                                    table_cell += "<table:covered-table-cell/>";
                                    break;
                                case "刪除知識":
                                    attributes += string.Format("table:style-name='HeaderTableCell' table:number-columns-spanned='3'");
                                    className = "CenterWord";
                                    table_cell += "<table:covered-table-cell/>";
                                    table_cell += "<table:covered-table-cell/>";
                                    break;
                                case "合計":
                                    attributes += string.Format("table:style-name='HeaderTableCell' table:number-rows-spanned='2'");
                                    className = "CenterWord";
                                    break;

                                default:
                                    continue;

                            }

                        }
                        if (td.className == "secondColumn")
                        {
                            switch (td.data)
                            {
                                case "順序":
                                    tds += " <table:covered-table-cell/>";
                                    continue;
                                case "審核起始日":
                                    tds += " <table:covered-table-cell/>";
                                    continue;

                                case "合計":
                                    tds += " <table:covered-table-cell/>";
                                    continue;
                                case "新增知識審核":
                                    attributes += string.Format("table:style-name='HeaderTableCell'");
                                    className = "CenterWord";
                                    data = "審核中";
                                    break;
                                case "新增知識生效":
                                    attributes += string.Format("table:style-name='FooterTableCell'");
                                    className = "CenterWord";
                                    data = "生效";
                                    break;

                                case "新增知識退件":
                                    attributes += string.Format("table:style-name='HeaderTableCell'");
                                    className = "CenterWord";
                                    data = "退件";
                                    break;
                                case "修改知識審核":
                                    attributes += string.Format("table:style-name='HeaderTableCell'");
                                    className = "CenterWord";
                                    data = "審核中";
                                    break;
                                case "修改知識生效":
                                    attributes += string.Format("table:style-name='FooterTableCell'");
                                    className = "CenterWord";
                                    data = "生效";
                                    break;

                                case "修改知識退件":
                                    attributes += string.Format("table:style-name='HeaderTableCell'");
                                    className = "CenterWord";
                                    data = "退件";
                                    break;
                                case "刪除知識審核":
                                    attributes += string.Format("table:style-name='HeaderTableCell'");
                                    className = "CenterWord";
                                    data = "審核中";
                                    break;
                                case "刪除知識生效":
                                    attributes += string.Format("table:style-name='FooterTableCell'");
                                    className = "CenterWord";
                                    data = "生效";
                                    break;

                                case "刪除知識退件":
                                    attributes += string.Format("table:style-name='HeaderTableCell'");
                                    className = "CenterWord";
                                    data = "退件";
                                    break;
                                default:
                                    continue;

                            }

                        }
```
其餘部分，大多數皆相同。
## Method
###   `AmountReport`

| 名稱	  |    類型   |  描述     |
| -------- | -------- | -------- |
|  AmountReport<T>(T[] data, string[] cols, string title,string dateTime,  string Creator, bool end = false)| AmountReport  | 組合成報表相關資料    |



| Args     |  描述     |
| -------- | -------- |
| data     |   表格內資料    |
|  cols    |   欲顯示的表格標頭|
| title    |   標題|       
|dateTime  |   文件建立時間|
|Creator   |   建立者|
|end       |   判斷是否要形成總結，預設為 `NULL`|

### `setcut`
| 名稱	  |    類型   |  描述     |
| -------- | -------- | -------- |
|  setcut(cols)| void | 傳入欲顯示欄位標題之陣列    |



| Args     |  描述     |
| -------- | -------- |
| cols     |   表格欄位資料，陣列    |

### `setTile`
| 名稱	  |    類型   |  描述     |
| -------- | -------- | -------- |
|  setTile(title)| void | 傳入標題名稱   |



| Args     |  描述     |
| -------- | -------- |
| title     |  標題名稱    |

### `setCreator`
| 名稱	  |    類型   |  描述     |
| -------- | -------- | -------- |
| setCreator(Creator)| void | 傳入製作者名稱   |



| Args     |  描述     |
| -------- | -------- |
| Creator     |  製作者名稱    |

### `setCreatedDate`
| 名稱	  |    類型   |  描述     |
| -------- | -------- | -------- |
| setCreatedDate(dateTime)| void | 傳入製作日期  |



| Args     |  描述     |
| -------- | -------- |
| dateTime |  製作日期    |

### `setData`
| 名稱	  |    類型   |  描述     |
| -------- | -------- | -------- |
| setData(data)| void     | 傳入表格內資料         |



| Args     |  描述     |
| -------- | -------- |
| data |  表格資料   |
### `setsum`
| 名稱	  |    類型   |  描述     |
| -------- | -------- | -------- |
| setsum(data)| void     | 傳入表格資料計算出資料總和         |



| Args     |  描述     |
| -------- | -------- |
| data |  表格資料   |

### 其他method
| 名稱	  |    類型   |  描述     |
| -------- | -------- | -------- |
|  getColCount()| int     | 回傳表格欄數    |
|render(int? width) |string |回傳完整的xml字串，`width` 為表格寬度，可顯示為空值|
| render()  | string |組成各段xml片段|
|changecut(string[] cut)|void|塞入欲顯示欄位的陣列進入新的陣列中|
|setWord(string author = null, string company = null, string sheetName = null)|void |設定表格資料|
|appendFullRow(string data, string trStyle = null, string className = null)|ModelTR |將表格資料塞入ModelTR，用以之後使用，主要為塞入文件相關資料。`trStyle`給予表格樣式語法，預設為null。`className` 給予資料className設定，預設為null|
|appendRow(params object[] data)|ModelTR|將表格資料塞入ModelTR，用以之後使用，主要為塞入表格標題以及表格資料。|
|appendTable<T>(T[] data, string trStyle = null, string className = null)|void|將表格資料塞入ModelTR，用以之後使用，主要為塞入表格內容資料|
## DataTable 資料型態 形成odt
dataTable的資料組成 塞了6種欄位資料
欲顯示的資料有4種 col
```csharp=
 DataTable dtTable = new DataTable("test");
            DataRow row;
            // 建立欄位
            DataColumn[] colss ={
                                  new DataColumn("ID",typeof(int)),
                                  new DataColumn("標題",typeof(string)),
                                  new DataColumn("姓名",typeof(string)),
                                  new DataColumn("編號",typeof(decimal)),
                                  new DataColumn("資料",typeof(string)),
                                  new DataColumn("電話",typeof(string))
                              };
            dtTable.Columns.AddRange(colss);
            
            // 新增資料到DataTable
            for (int i = 1; i <= 10; i++)
            {
                string a = Guid.NewGuid().ToString("N");
                row = dtTable.NewRow();
                row["ID"] = i;
                row["標題"] = "測試 " + i.ToString();
                row["姓名"] = "SOL_" + i;
                row["編號"] = "123";
                row["資料"] = a.ToString();
                row["電話"] = "0923456789";
                dtTable.Rows.Add(row);
            }
            //
             string[] cols = new string[6];

            cols[0] = "姓名";
            cols[1] = "資料";
            cols[2] = "ID";
            cols[3] = "電話";
            //多帶入dtTable 
 Odt odtRes = Rpt.OdtResponse(data, cols, title,DateTime.Now.AddDays(-1), DateTime.Now, "林家弘", true,dtTable);
```
```csharp=
  public OdtReport OdtResponse<T>(T[] data, string[] cols, string title, DateTime starting, DateTime ending, string Creator, bool end = false)
        {
            OdtReport orp = new OdtReport(typeof(T));
            if (cols.Length > 0)
            {
                orp.setcut(cols);
            }

            orp.setTile(title);
            orp.setDate(starting, ending);
            orp.setCreator(Creator);
            orp.setCreatedDate();
            orp.setColumn();
            orp.setData(data);

            if (end) //如果要顯示結算筆數 end =true;
            {
                orp.setsum(data);
            }
            return orp;

        }
```
```csharp=
        public void setData (DataTable data)
        {
            appendTable(data);
        }
```
將dataTable資料 抓取欄位值(column)跟欲顯示欄位(cols)對應，找出顯示欄位，並與資料作對應。
```csharp=
  public void appendTable(DataTable data, string trStyle = null, string className = null)
        {
            for (int i = 0; i < data.Rows.Count; i++)
            {
                ModelTD[] tds = new ModelTD[cols.Length];
                ModelTR tr = new ModelTR();
                tr.tds = new List<ModelTD>();
                tr.style = trStyle;
                tr.className = className;

                foreach (var prop in data.Columns)
                {
                    try
                    {
                        var column = prop;
                        int colinx = Array.IndexOf(cols, column.ToString());
                        if (colinx == -1) continue;
                        var value = data.Rows[i][column.ToString()];
                        tds[colinx] = new ModelTD()
                        {
                            data = value
                        };
                    }
                    catch (Exception)
                    {
                        continue;
                    }
                }
                foreach (ModelTD td in tds)
                    tr.tds.Add(td);
                trs.Add(tr);
            }
        }
```
data.select().count() 算出總比數
```csharp=
       public  void setsum(DataTable data) //總筆數
        {
            string lastRowStyle = "TotalCell"; //預設CSS
            string lastClassName = "Word";
            appendRow(new { value = data.Select().Count(), colspan = getColCount() - 1, style = lastRowStyle, className = lastClassName });//統計資料數

        }

```
## Refactor Code
### interface
全通用標準報表規格
```csharp=
namespace ReportX.Rep.Common
{
    public interface IReportX
    {
        string render(int? width = null);
        void changecut(string[] cut);
        void setCustomStyle(string css);
        ModelTR appendFullRow(string data, string trStyle = null, string className = null);
        ModelTR appendRow(params object[] data);
        void appendTable<T>(T[] data, string trStyle = null, string className = null);
        void appendTable(DataTable data, string trStyle = null, string className = null);
        void setData(string author = null, string company = null, string sheetName = null, string dateTime = null, string dateRange = null);
        int getColCount();
    }
}

```
### abstract
#### openoffice

各個檔案皆需要制定各自必要規格
> render()
> changecut()
> setCustomStyle()
> appendFullRow()
>  setData()
```csharp=
namespace ReportX.Rep.Common
{
    public abstract class AbsOpenOffice: IReportX
    {
        protected abstract string[] oldcols { get; set; }
        protected abstract string[] newcols { get; set; }
        public abstract string[] cols { get; set; }
        protected abstract List<ModelTR> trs { get; }


        public abstract string render( int? width = null);
        public abstract void changecut(string[] cut);
        public abstract void setCustomStyle(string css);
        public abstract ModelTR appendFullRow(string data, string trStyle = null, string className = null);  
        public abstract void setData(string author = null, string company = null, string sheetName = null, string dateTime = null, string dateRange = null);

        public ModelTR appendRow(params object[] data)
        {
            ModelTR tr = new ModelTR();
            tr.tds = new List<ModelTD>();

            foreach (object cell in data)
            {

                ModelTD td = new ModelTD();
                var value = cell.GetType().GetProperty("value");

                if (value == null)
                {
                    td.data = cell.ToString();
                }
                else
                {
                    var colspan = cell.GetType().GetProperty("colspan");
                    var rowspan = cell.GetType().GetProperty("rowspan");
                    var fontSize = cell.GetType().GetProperty("fontSize");
                    var align = cell.GetType().GetProperty("align");
                    var bold = cell.GetType().GetProperty("bold");
                    var style = cell.GetType().GetProperty("style");
                    var className = cell.GetType().GetProperty("className");

                    if (value != null) td.data = value.GetValue(cell, null);
                    if (colspan != null) td.colspan = (int)colspan.GetValue(cell, null);
                    if (rowspan != null) td.rowspan = (int)rowspan.GetValue(cell, null);
                    if (fontSize != null) td.fontSize = fontSize.GetValue(cell, null).ToString();
                    if (align != null) td.align = align.GetValue(cell, null).ToString();
                    if (bold != null) td.bold = true;
                    if (style != null) td.style = style.GetValue(cell, null).ToString();
                    if (className != null) td.className = className.GetValue(cell, null).ToString();
                }
                tr.tds.Add(td);

            }
            trs.Add(tr);
            return tr;
        }
        public void appendTable<T>(T[] data, string trStyle = null, string className = null)
        {

            foreach (T tuple in data)
            {
                ModelTD[] tds = new ModelTD[cols.Length];
                ModelTR tr = new ModelTR();
                tr.tds = new List<ModelTD>();
                tr.style = trStyle;
                tr.className = className;
                foreach (var prop in tuple.GetType().GetProperties())
                {
                    try
                    {
                        Present attr = prop.GetCustomAttribute<Present>();
                        if (attr == null) continue;
                        var asdf = attr.getName();
                        int colinx = Array.IndexOf(cols, attr.getName());
                        object value = prop.GetValue(tuple, null);
                        tds[colinx] = new ModelTD()
                        {
                            col = attr.getName(),
                            data = value
                        };
                    }
                    catch (Exception)
                    {
                        continue;
                    }
                }
                foreach (ModelTD td in tds)
                    tr.tds.Add(td);

                trs.Add(tr);
            }
        }
        public void appendTable(DataTable data, string trStyle = null, string className = null)
        {
            for (int i = 0; i < data.Rows.Count; i++)
            {
                ModelTD[] tds = new ModelTD[cols.Length];
                ModelTR tr = new ModelTR();
                tr.tds = new List<ModelTD>();
                tr.style = trStyle;
                tr.className = className;

                foreach (var prop in data.Columns)
                {
                    try
                    {
                        var test = prop;
                        int colinx = Array.IndexOf(cols, test.ToString());
                        if (colinx == -1) continue;
                        var value = data.Rows[i][test.ToString()];
                        tds[colinx] = new ModelTD()
                        {
                            data = value
                        };
                    }
                    catch (Exception)
                    {
                        continue;
                    }
                }
                foreach (ModelTD td in tds)
                    tr.tds.Add(td);
                trs.Add(tr);
            }
        }
        public int getColCount()
        {
            return cols.Length;
        }
        public void CreateMeta(string type)
        {
            var str = "";
            switch (type)
            {
                case "odt":
                    str = "<?xml version='1.0' encoding='UTF-8' standalone='yes'?><manifest:manifest xmlns:manifest='urn:oasis:names:tc:opendocument:xmlns:manifest:1.0'><manifest:file-entry manifest:full-path='/' manifest:media-type='application/vnd.oasis.opendocument.text'/><manifest:file-entry manifest:full-path='content.xml' manifest:media-type='text/xml'/><manifest:file-entry manifest:full-path='settings.xml' manifest:media-type='text/xml'/><manifest:file-entry manifest:full-path='styles.xml' manifest:media-type='text/xml'/><manifest:file-entry manifest:full-path='meta.xml' manifest:media-type='text/xml'/></manifest:manifest>";
                    break;
                case "ods":
                    str = "<?xml version='1.0' encoding='UTF-8' standalone='yes'?><manifest:manifest xmlns:manifest='urn:oasis:names:tc:opendocument:xmlns:manifest:1.0'><manifest:file-entry manifest:full-path='/' manifest:media-type='application/vnd.oasis.opendocument.spreadsheet'/><manifest:file-entry manifest:full-path='styles.xml' manifest:media-type='text/xml'/><manifest:file-entry manifest:full-path='content.xml' manifest:media-type='text/xml'/><manifest:file-entry manifest:full-path='meta.xml' manifest:media-type='text/xml'/></manifest:manifest>";
                    break;
                default:
                    break;
            }
         string dirPath = @".\META-INF";
            if (Directory.Exists(dirPath))
            {
                if (File.Exists("META-INF/manifest.xml"))
                    File.Delete("META-INF/manifest.xml");
                File.AppendAllText("META-INF/manifest.xml", str);
            }
            else
            {
                Directory.CreateDirectory(dirPath);
                if (File.Exists("META-INF/manifest.xml"))
                    File.Delete("META-INF/manifest.xml");
                File.AppendAllText("META-INF/manifest.xml", str);
            }
        }
       
    }
}

```
#### office
各個檔案皆需要制定各自必要規格
> changecut()
> setCustomStyle()
> appendFullRow()
>  setData()
由於多載，用virtual 由各個加以定義
>render()
```csharp=
namespace ReportX.Rep.Common
{
    public abstract class AbsOffice: IReportX
    {
        protected abstract string[] oldcols { get; set; }
        protected abstract string[] newcols { get; set; }

        public abstract string[] cols { get; set; }
        protected abstract List<ModelTR> trs { get; }

        public virtual string render(int? width = null, string File_type = null)
        {
            throw new NotImplementedException();
        }
        public virtual string render(int? width = null)
        {
            throw new NotImplementedException();
        }
        public abstract void changecut(string[] cut);
        public abstract void setCustomStyle(string css);
        public abstract ModelTR appendFullRow(string data, string trStyle = null, string className = null);
        public abstract void setData(string author = null, string company = null, string sheetName = null, string dateTime = null, string dateRange = null);
        public ModelTR appendRow(params object[] data)
        {
            ModelTR tr = new ModelTR();
            tr.tds = new List<ModelTD>();

            foreach (object cell in data)
            {

                ModelTD td = new ModelTD();
                var value = cell.GetType().GetProperty("value");

                if (value == null)
                {
                    td.data = cell.ToString();
                }
                else
                {
                    var colspan = cell.GetType().GetProperty("colspan");
                    var rowspan = cell.GetType().GetProperty("rowspan");
                    var fontSize = cell.GetType().GetProperty("fontSize");
                    var align = cell.GetType().GetProperty("align");
                    var bold = cell.GetType().GetProperty("bold");
                    var style = cell.GetType().GetProperty("style");
                    var className = cell.GetType().GetProperty("className");

                    if (value != null) td.data = value.GetValue(cell, null);
                    if (colspan != null) td.colspan = (int)colspan.GetValue(cell, null);
                    if (rowspan != null) td.rowspan = (int)rowspan.GetValue(cell, null);
                    if (fontSize != null) td.fontSize = fontSize.GetValue(cell, null).ToString();
                    if (align != null) td.align = align.GetValue(cell, null).ToString();
                    if (bold != null) td.bold = true;
                    if (style != null) td.style = style.GetValue(cell, null).ToString();
                    if (className != null) td.className = className.GetValue(cell, null).ToString();
                }
                tr.tds.Add(td);

            }
            trs.Add(tr);
            return tr;
        }
        public void appendTable<T>(T[] data, string trStyle = null, string className = null)
        {

            foreach (T tuple in data)
            {
                ModelTD[] tds = new ModelTD[cols.Length];
                ModelTR tr = new ModelTR();
                tr.tds = new List<ModelTD>();
                tr.style = trStyle;
                tr.className = className;
                foreach (var prop in tuple.GetType().GetProperties())
                {
                    try
                    {
                        Present attr = prop.GetCustomAttribute<Present>();
                        if (attr == null) continue;
                        var asdf = attr.getName();
                        int colinx = Array.IndexOf(cols, attr.getName());
                        object value = prop.GetValue(tuple, null);
                        tds[colinx] = new ModelTD()
                        {
                            col = attr.getName(),
                            data = value
                        };
                    }
                    catch (Exception)
                    {
                        continue;
                    }
                }
                foreach (ModelTD td in tds)
                    tr.tds.Add(td);

                trs.Add(tr);
            }
        }
        public void appendTable(DataTable data, string trStyle = null, string className = null)
        {
            for (int i = 0; i < data.Rows.Count; i++)
            {
                ModelTD[] tds = new ModelTD[cols.Length];
                ModelTR tr = new ModelTR();
                tr.tds = new List<ModelTD>();
                tr.style = trStyle;
                tr.className = className;

                foreach (var prop in data.Columns)
                {
                    try
                    {
                        var test = prop;
                        int colinx = Array.IndexOf(cols, test.ToString());
                        if (colinx == -1) continue;
                        var value = data.Rows[i][test.ToString()];
                        tds[colinx] = new ModelTD()
                        {
                            data = value
                        };
                    }
                    catch (Exception)
                    {
                        continue;
                    }
                }
                foreach (ModelTD td in tds)
                    tr.tds.Add(td);
                trs.Add(tr);
            }
        }
        public int getColCount()
        {
            return cols.Length;
        }

    }
}
```
### class

各種格式 設定各自的報表名稱
>getsheetName()
```csharp=
        public string getsheetName()
        {
            return excel.sheetName;
        }
```
### ReportCreator
建立標準建立方法
>ReportCreator<T>
```csharp=

    public class ReportCreator<T> where T : IReportX
    {
        static T report { get; set; }


        public MemberInfo[] modeli;
        protected Type type { get; set; }
        protected string[] oldcols { get; set; }
        protected string[] newcols { get; set; }
        protected List<ModelTR> trs { get; }
        public static string[] cols { get; set; }
        public string sheetName { get; set; }
        private ModelExcel excel;
        private ModelWord word;
        private ModelOdt odt;

        public ReportCreator(Type type)
        {
            List<MemberInfo> list_cols = new List<MemberInfo>();
            modeli = type.GetMembers();
            foreach (var member in type.GetMembers())
            {
                Present attr = member.GetCustomAttribute<Present>();
                if (attr == null) continue;

                int MetadataToken = member.MetadataToken,
                    inserted_index = 0;

                // sory by MetadataToken (declaration)
                for (int i = 0; i < list_cols.Count; i++)
                {
                    inserted_index = i;
                    if (MetadataToken < list_cols[i].MetadataToken) break;
                    inserted_index = i + 1;
                }
                list_cols.Insert(inserted_index, member);
            }
            string[] str_cols = new string[list_cols.Count]; //取得標題數量

            for (int i = 0; i < list_cols.Count; i++)
                str_cols[i] = list_cols[i].GetCustomAttribute<Present>().getName();//取得標題名稱

            oldcols = str_cols; //舊的陣列
            cols = str_cols;
            report = (T)Activator.CreateInstance(typeof(T), type);
        }
        public string render(int? width = null)
        {
         
            return report.render(width);
        }


        public void setDate(DateTime from, DateTime? to = null, string type = null)
        {
            if (from == null) return;
            if (to == null) to = DateTime.Now;

            string date_start = Convert.ToDateTime(from).ToString("yyyy/MM/dd"),
                   date_end = Convert.ToDateTime(to).ToString("yyyy/MM/dd");
            switch (type)
            {
                case "Word":
                    report.appendFullRow(string.Format("{0} - {1}", date_start, date_end), null, "r-header-date");
                    break;
                case "Excel":
                    report.appendFullRow(string.Format("{0} - {1}", date_start, date_end), null, "r-header-date");
                    break;
                case "Odt":
                    report.appendFullRow(string.Format("{0} - {1}", date_start, date_end), "TableCellData", "TitleDateWord");
                    break;
                case "Ods":
                    report.appendFullRow(string.Format("{0} - {1}", date_start, date_end), "TableCellData", "TitleDateWord");
                    break;
                default:
                    break;
            }
        }
        public void setCreator(string creator, string type = null)
        {
            report.setData(author: creator);
            switch (type)
            {
                case "Word":
                    report.appendFullRow(string.Format("製表人：{0}", creator), null, "r-header-secondary");
                    break;
                case "Excel":
                    report.appendFullRow(string.Format("製表人：{0}", creator), null, "r-header-secondary");
                    break;
                case "Odt":
                    report.appendFullRow(string.Format("製表人：{0}", creator), "TableCellData", "TitleTimeWord");
                    break;
                case "Ods":
                    report.appendFullRow(string.Format("製表人：{0}", creator), "TableCellData", "TitleTimeWord");
                    break;
                default:
                    break;
            }
        }
        public void setTile(string title, string type = null)
        {
            report.setData(sheetName: title);
            switch (type)
            {
                case "Word":
                    report.appendFullRow(title, null, "r-header-title");
                    break;
                case "Excel":
                    report.appendFullRow(title, null, "r-header-title");
                    break;
                case "Odt":
                    report.appendFullRow(title, "TableCellData", "Title");
                    break;
                case "Ods":
                    report.appendFullRow(title, "TableCellData", "Title");
                    break;
                default:
                    break;
            }

        }
        public void setCreatedDate(string type = null)
        {
            string now = Convert.ToDateTime(DateTime.Now).ToString("yyyy/MM/dd hh:mm:tt");
            switch (type)
            {
                case "Word":
                    report.appendFullRow(string.Format("製表時間：{0}", now), null, "r-header-secondary");
                    break;
                case "Excel":
                    report.appendFullRow(string.Format("製表時間：{0}", now), null, "r-header-secondary");
                    break;
                case "Odt":
                    report.appendFullRow(string.Format("製表時間：{0}", now), "TableCellData", "TitleTimeWord");
                    break;
                case "Ods":
                    report.appendFullRow(string.Format("製表時間：{0}", now), "TableCellData", "TitleTimeWord");
                    break;
                default:
                    break;
            }
        }

        public void setColumn()
        {
            var intersectResult = oldcols.Intersect(newcols);
            cols = intersectResult.ToArray();
            ModelTR col = report.appendRow(cols);
            foreach (ModelTD td in col.tds)
                td.className = "column";
        }


        public void setData<T>(T[] data)
        {
            report.appendTable(data);
        }

        public void setsum<T>(T[] data, string type) //總筆數
        {
            string lastRowStyle = "";
            string lastClassName = "";
            switch (type)
            {
                case "Word":
                    lastRowStyle = "background-color:#DDD;-webkit-print-color-adjust: exact;"; //預設CSS
                    report.appendRow(new { value = "總筆數", colspan = report.getColCount() - 1, style = lastRowStyle }, data.Length);//統計資料數
                    break;
                case "Excel":
                    lastRowStyle = "background-color:#DDD;-webkit-print-color-adjust: exact;"; //預設CSS
                    report.appendRow(new { value = "總筆數", colspan = report.getColCount() - 1, style = lastRowStyle }, data.Length);//統計資料數
                    break;
                case "Odt":
                    lastRowStyle = "TotalCell"; //預設CSS
                    lastClassName = "Word";
                    report.appendRow(new { value = data.Length, colspan = report.getColCount() - 1, style = lastRowStyle, className = lastClassName });//統計資料數                    break;
                    break;
                case "Ods":
                    lastRowStyle = "TotalCell"; //預設CSS
                    lastClassName = "Word";
                    report.appendRow(new { value = data.Length, colspan = report.getColCount() - 1, style = lastRowStyle, className = lastClassName });//統計資料數
                    break;
                default:
                    break;
            }

        }

        // 傳入欲顯示欄位標題 之陣列
        public void setcut(string[] cut)
        {
            newcols = cut;
            report.changecut(cut);
        }
        public void CreateMeta(string type)
        {
            var str = "";
            switch (type)
            {
                case "odt":
                    str = "<?xml version='1.0' encoding='UTF-8' standalone='yes'?><manifest:manifest xmlns:manifest='urn:oasis:names:tc:opendocument:xmlns:manifest:1.0'><manifest:file-entry manifest:full-path='/' manifest:media-type='application/vnd.oasis.opendocument.text'/><manifest:file-entry manifest:full-path='content.xml' manifest:media-type='text/xml'/><manifest:file-entry manifest:full-path='settings.xml' manifest:media-type='text/xml'/><manifest:file-entry manifest:full-path='styles.xml' manifest:media-type='text/xml'/><manifest:file-entry manifest:full-path='meta.xml' manifest:media-type='text/xml'/></manifest:manifest>";
                    break;
                case "ods":
                    str = "<?xml version='1.0' encoding='UTF-8' standalone='yes'?><manifest:manifest xmlns:manifest='urn:oasis:names:tc:opendocument:xmlns:manifest:1.0'><manifest:file-entry manifest:full-path='/' manifest:media-type='application/vnd.oasis.opendocument.spreadsheet'/><manifest:file-entry manifest:full-path='styles.xml' manifest:media-type='text/xml'/><manifest:file-entry manifest:full-path='content.xml' manifest:media-type='text/xml'/><manifest:file-entry manifest:full-path='meta.xml' manifest:media-type='text/xml'/></manifest:manifest>";
                    break;
                default:
                    break;
            }
            string dirPath = @".\META-INF";
            if (Directory.Exists(dirPath))
            {
                if (File.Exists("META-INF/manifest.xml"))
                    File.Delete("META-INF/manifest.xml");
                File.AppendAllText("META-INF/manifest.xml", str);
            }
            else
            {
                Directory.CreateDirectory(dirPath);
                if (File.Exists("META-INF/manifest.xml"))
                    File.Delete("META-INF/manifest.xml");
                File.AppendAllText("META-INF/manifest.xml", str);
            }
        }
        public int getColCount()
        {
            return cols.Length;
        }
    }
```