zoukankan      html  css  js  c++  java
  • 利用XSD配合XSLT產出特定格式Word檔案 -摘自网络

    利用類別產生XSD檔

    產出XSD檔的目的在於提供Word樣板設計之資料框架

    在此使用微軟提供之XML Schema Definition Tool (Xsd.exe)工具產生XSD檔

    1. 定義類別

    01 // 書籍資料
    02 public class Book
    03 {
    04     public string BookId { get; set; }
    05     public string Name { get; set; }
    06     public string price { get; set; }
    07 }
    08  
    09 // 訂單資料
    10 public class Order
    11 {
    12     public string BuyerName { get; set; }
    13     public List<Book> Books { get; set; }
    14     public int TotalPrice { get; set; }
    15 }

    2. 使用Xsd.exe工具產生XSD檔案

       工具位置: C:Program Files (x86)Microsoft SDKsWindowsv8.1AinNETFX 4.5.1 Tools

       工具語法: xsd D:ProjectsWordGenerator.exe /language:CS /outputdir:d:ProjectsXsd /type:Order

    3. XSD內容如下

    01 <?xml version="1.0" encoding="utf-8"?>
    02 <xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    03   <xs:element name="Order" nillable="true" type="Order" />
    04   <xs:complexType name="Order">
    05     <xs:sequence>
    06       <xs:element minOccurs="0" maxOccurs="1" name="BuyerName" type="xs:string" />
    07       <xs:element minOccurs="0" maxOccurs="1" name="Books" type="ArrayOfBook" />
    08       <xs:element minOccurs="1" maxOccurs="1" name="TotalPrice" type="xs:int" />
    09     </xs:sequence>
    10   </xs:complexType>
    11   <xs:complexType name="ArrayOfBook">
    12     <xs:sequence>
    13       <xs:element minOccurs="0" maxOccurs="unbounded" name="Book" nillable="true" type="Book" />
    14     </xs:sequence>
    15   </xs:complexType>
    16   <xs:complexType name="Book">
    17     <xs:sequence>
    18       <xs:element minOccurs="0" maxOccurs="1" name="BookId" type="xs:string" />
    19       <xs:element minOccurs="0" maxOccurs="1" name="Name" type="xs:string" />
    20       <xs:element minOccurs="0" maxOccurs="1" name="price" type="xs:string" />
    21     </xs:sequence>
    22   </xs:complexType>
    23 </xs:schema>

    4. 加上Namespace

       targetNamespace=http://schemas.chris.com/WordGenerator/Order.xsd

       xmlns=http://schemas.chris.com/WordGenerator/Order.xsd

       image

    利用XSD檔產生特定格式之Word檔

    筆者是以Word 2010進行實作,相關實作畫面如下。另外,若使用Word 2013的朋友是無法透過此方法自行定義XML標記的,因為移除自訂 XML 標記是2009年12月22日美國法院的判決結果,購買或取得 Word 2013 授權的客戶會發現此軟體不含特定的自訂 XML 標記實作;所以請使用非Word2013版本來實作此步驟。

    http://support.microsoft.com/kb/2761189/zh-tw

    1. 加入開發人員工具列

       image

    2. 點選開發人員工具列之結構描述

       image

    3. 選擇剛產生之XSD檔案

       image

       image

       image

    4. 開始編輯畫面與資料關聯

       目前希望呈現的樣式(黃色是隨資料異動部分)

       image

       點選結構後,產生XML結構工具

       imageimage

       圈選Order對應部分後,點選Order

       image

       此時會出現選取範圍,就選擇僅套用至選取範圍即可

       image

       此時就完成了第一次的資料對應關係

      image

      然後依序處理其他部分,結果如下

      image

      此時若發現有錯誤發生

      image

       調整一下XML選項設定即可

       image

       image

       調整完畢後儲存為DOC檔案供下次修改使用

    利用特定格式之Word檔產生XSLT檔

    1. 下載安裝 Word 2003: XML SDK

        http://www.microsoft.com/downloads/details.aspx?familyid=ca83cb4f-8dee-41a3-9c25-dd889aea781c&displaylang=en

    2. 將Word檔另存為XML

       image

    3. 利用WML2XSLT.exe 將 Order.xml 轉換成 Order.xslt

       image

       點選所需的namespace即可

       image

    組合資料產生Word檔

    資料 + 顯示樣式

        = 資料物件序列化(XML) + XSLT

        = 產生具有資料及指定樣式Word檔

    01 private void CreateWord()
    02 {
    03  
    04     string xsltLocation = @"D:Order.xslt";
    05     string outputPath = @"D:Order.doc";
    06  
    07     // Data
    08     Order order = new Order()
    09     {
    10         BuyerName = "Chris Chen",
    11         TotalPrice = 600,
    12         Books = new List<Book>()
    13         {
    14             new Book(){BookId="B001", Name="Name01", price="100"},
    15             new Book(){BookId="B002", Name="Name02", price="200"},
    16             new Book(){BookId="B003", Name="Name03", price="300"},
    17         }
    18     };
    19  
    20     // Data XML (一定要namespace)
    21     string szInputXml = Serialize(order, "http://schemas.chris.com/WordGenerator/Order.xsd");
    22     XmlTextReader xmlReader = new XmlTextReader(new System.IO.StringReader(szInputXml));
    23  
    24     // XSLT
    25     XmlReader xsltReader = XmlReader.Create(xsltLocation);
    26  
    27     // Create Word
    28     byte[] wordDoc = GetWord(xmlReader, xsltReader);
    29  
    30     // Write resulting array to HDD, show process information
    31     using (FileStream fs = new FileStream(outputPath, FileMode.Create))
    32         fs.Write(wordDoc, 0, wordDoc.Length);
    33  
    34     // Display resulting report in Word
    35     Process.Start(new ProcessStartInfo(outputPath));
    36 }
    37  
    38 public string Serialize(object obj, string defaultNamespace)
    39 {
    40     // encoding issue: utf-16 => utf-8
    42  
    43     XmlSerializer xs = new XmlSerializer(obj.GetType(), defaultNamespace);
    44  
    45     MemoryStream stream = new MemoryStream();
    46     XmlWriterSettings setting = new XmlWriterSettings();
    47     setting.Encoding = new UTF8Encoding(false);
    48     setting.Indent = true;
    49     
    50     using (XmlWriter writer = XmlWriter.Create(stream, setting))
    51     { xs.Serialize(writer, obj); }
    52  
    53     return Encoding.UTF8.GetString(stream.ToArray());
    54 }
    55  
    56 public static byte[] GetWord(XmlReader xmlData, XmlReader xsltReader)
    57 {
    58     XslCompiledTransform xslt = new XslCompiledTransform();
    59     XsltArgumentList args = new XsltArgumentList();
    60  
    61     using (MemoryStream swResult = new MemoryStream())
    62     {
    63         // Load XSLT to reader and perform transformation
    64         xslt.Load(xsltReader);
    65         xslt.Transform(xmlData, args, swResult);
    66  
    67         return swResult.ToArray();
    68     }
    69 }

    結果如同我們所預期的將資料都填入Word檔中

    image

    期望效益

    1. 開發過程可集中於資料模型的設計(類似ViewModel概念)

    2. Word樣式可供客戶自行調整 (不變更資料項目為前提下,僅需自動轉為XSLT檔即可)

    3. 資料自動綁定至Word並產生檔案輸出

    參考資料

    http://www.codeproject.com/Articles/20287/Generating-Word-Reports-Documents

    http://msdn.microsoft.com/en-us/library/x6c1kb0s(v=vs.110).aspx

    http://blogs.msdn.com/b/williamcornwill/archive/2007/01/17/document-generation-using-wordml-word-2003.aspx

  • 相关阅读:
    遇到的问题
    getContextPath、getServletPath、getRequestURI的区别
    js判断是否是ie浏览器
    js判断浏览器类型和版本
    最短JS判断是否为IE6(IE的写法)
    Console命令详解,让调试js代码变得更简单
    让table中td的内容靠上对齐
    <c:out>标签中的escapeXML属性
    指纹识别技术设计的注意事项
    嵌入式指纹检索系统设计
  • 原文地址:https://www.cnblogs.com/haoliansheng/p/4338542.html
Copyright © 2011-2022 走看看