OpenXML 讀寫 docx

1 篇文章 / 0 new
author
OpenXML 讀寫 docx
OpenXML操作不太人性化, 常須注意Elements結構及類型, 基本類如下

使用Open XML SDK 2.5,可以建立文件結構及使用對應至WordprocessingML元素的強型別類別的內容。

WordprocessingML 元素

Open XML SDK 2.5類別

描述

文件

Document

主要的文件組件的根元素。

body

Body

封鎖層級結構,例如段落、 表格、 註解和其他人的ISO/IEC 29500規格中指定的容器。

p

Paragraph

段落。

r

Run

文字流。

t

Text

文字範圍。


常用操作
► 開啟檔案
byte[] fs = File.ReadAllBytes(HttpContext.Current.Server.MapPath("~/Download/11.docx"));
MemoryStream ms = new MemoryStream(fs);
WordprocessingDocument doc = WordprocessingDocument.Open(ms,true);
► 讀寫 table 內容
//取出第一個Table
Table tbl = doc.MainDocumentPart.Document.Body.Elements<Table>().First();
//取得TableRow陣列
TableRow[] rows = tbl.Elements<TableRow>().ToArray();
for (int i = 0; i < rows.Length; i++)
{
    //取得TableRow的TableCell陣列
    var cells = rows[i].Elements<TableCell>().ToArray();
    //顯示每列的內容
    for (int j = 0; j < cells.Length; j++)
    {
        Debug.Print("Row:{0} Cell:{1} Value={2}", i, j, cells[j].Elements<Paragraph>().First().InnerText);
        Debug.Print(cells[j].Elements<Paragraph>().First().InnerXml);
        //修改內容
        OpenXmlElement p = cells[j].Elements<Paragraph>().Last();
        if (p.HasChildren)
        {//空格內要先放一個空白文字, 若原cell為空, 通常無 Run 元素
            //int cnt = p.Elements<Run>().Count();//亦可使用此方式檢查是否有該類型元素存在
            OpenXmlElement r = p.Elements<OpenXmlElement>().Last();
            if (r != null && r is Run)
            {
                Text t = r.Elements<Text>().First();
                t.Text = String.Format(t.Text,"aa", "a");
            }
        }
    }
}
► cell 水平合併
TableCellProperties cp = new TableCellProperties();
HorizontalMerge hm = new HorizontalMerge() { Val = MergedCellValues.Restart };
cp.Append(hm);
TableCellProperties cp1 = new TableCellProperties();
HorizontalMerge hm1 = new HorizontalMerge() { Val = MergedCellValues.Continue };
cp1.Append(hm1);
(rows[0].Elements<TableCell>().ToArray())[0].Append(cp);
(rows[0].Elements<TableCell>().ToArray())[1].Append(cp1);
► cell 垂直合併
TableCellProperties cp2 = new TableCellProperties();
VerticalMerge hm2 = new VerticalMerge() { Val = MergedCellValues.Restart };
cp2.Append(hm2);
TableCellProperties cp3 = new TableCellProperties();
VerticalMerge hm3 = new VerticalMerge() { Val = MergedCellValues.Continue };
cp3.Append(hm3);
(rows[2].Elements<TableCell>().ToArray())[0].Append(cp2);
(rows[3].Elements<TableCell>().ToArray())[0].Append(cp3);
使用合併時須注意, 每個 cell 都有自己的 new TableCellProperties, 不能將一個 TableCellProperties 給於兩個 cell 會出錯
► http 輸出檔案
doc.MainDocumentPart.Document.Save();
string fName = "k.docx";
if (Request.Browser.Browser == "IE")//若使有文中檔名
    fName = Server.UrlPathEncode(fName);
Response.Clear();
Response.ClearHeaders();
Response.ClearContent();
Response.AddHeader("content-disposition", "attachment; filename=\""+fName+"\"");
Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
Response.ContentEncoding = Encoding.GetEncoding("ISO-8859-1");
ms.Position = 0;
ms.CopyTo(Response.OutputStream);
Response.End();
► 加入樣式
p.RemoveAllChildren();// p 為 TableCell.Elements<Paragraph>()
StyleRunProperties srp = new StyleRunProperties();
srp.Append(new RunFonts() { Ascii = "Tahoma", EastAsia = "標楷體", HighAnsi = "標楷體" });
srp.Append(new DocumentFormat.OpenXml.Wordprocessing.FontSize() { Val = "24" });
srp.Append(new Color() { Val = "00CC00" });//new Color() { ThemeColor = ThemeColorValues.Accent2 };
srp.Append(new Bold());
srp.Append(new Italic());
srp.Append(new Justification() { Val = JustificationValues.Center });//水平置中
Run run = new Run();
run.Append(srp);
run.Append(new Text("{0}") { Space = SpaceProcessingModeValues.Preserve });
p.Append(new TableCellVerticalAlignment() { Val = TableVerticalAlignmentValues.Center });//垂直置中
p.Append(run);
from https://msdn.microsoft.com/zh-tw/library/office/cc850835.aspx#sectionSec...