首頁 > 軟體

C#使用NPOI對word進行讀寫

2022-06-08 22:02:57

一、簡介

操作Word的類庫:

二、簡單使用

1、XWPFDocument類的範例化

該類的範例對應一個word檔案 

XWPFDocument MyDoc = new XWPFDocument();

2、設定頁面的大小

如果不進行頁面大小的設定,預設是縱向的A4大小。橫向的A4的頁面大小 ,如果要縱向,寬高兩個值調換即可。

T_SectPr m_SectPr = new CT_SectPr();       //範例一個尺寸類的範例
m_SectPr.pgSz.w = 16838;        //設定寬度(這裡是一個ulong型別)
m_SectPr.pgSz.h = 11906;        //設定高度(這裡是一個ulong型別)
MyDoc.Document.body.sectPr = m_SectPr;          //設定頁面的尺寸

這裡的單位比較特殊,用的是緹(Twip)這是一種和螢幕無關的長度單位,目的是為了讓應用程式元素輸出到不同裝置時都能保持一致的計算方式。

換算關係:

  • 1英寸=1440緹
  • 1釐米=567緹
  • 1磅=20緹
  • 1畫素=15緹

常用頁面尺寸:(單位Twip)

  • A4(縱向):W=11906 H=16838
  • A4(縱向):W=16838 H=11906
  • A5 : W=8390 H=11906
  • A6 : W=5953 H=8390

範例:控制word頁內邊距

//建立document物件
var doc = new XWPFDocument();
doc.Document.body.sectPr = new CT_SectPr();
CT_SectPr m_SectPr = doc.Document.body.sectPr;
m_SectPr.pgSz.h = (ulong)16838;
m_SectPr.pgSz.w = (ulong)11906;
//頁面邊距
m_SectPr.pgMar.left = (ulong)800;//左邊距
m_SectPr.pgMar.right = (ulong)800;//右邊距
m_SectPr.pgMar.top = "850";//上邊距
m_SectPr.pgMar.bottom = "850";//下邊距

3、段落處理

建立段落

段落為XWPFParagraph型別的範例,段落由XWPFDocument範例的使用CreateParagraph()方法生成。

XWPFParagraph MyParagraph = MyDoc.CreateParagraph();

該段落類有很多屬性,用於設定與段落相關的內容。主要有以下幾個方面

  • BorderXXXXX屬性:該值用於設定邊界的樣式。該屬性用於獲取或設定一個Borders列舉型別的值,
  • FillBackgroundColor屬性:背景填充的顏色。該屬性獲取或設定一個string型別的變數。該變數的含義是某個顏色的RGB值(在NPOI裡所有的顏色都是以這種形式表示的)。例如設定為黑色則對應的程式碼如下:
    MyParagraph.FillBackgroundColor = "#000000";
  • Alignment屬性:段落的對齊方式。該屬性獲取或設定一個ParagraphAlignment的列舉值。
  • VerticalAlignment屬性:文字垂直方向的對齊方式。該屬性獲取或設定一個TextAlignment 的列舉值。
  • IndentationFirstLine屬性:用於設定段落的首行縮排。該屬性獲取或設定一個int型變數。 
    這個int值並不是縮排的字數,這裡可以用一個函數計算縮排的距離。
//段落縮排   返回值為對應的縮排距離
//(fontname:文字型別名稱   fontsize:文字大小    fontcount:縮排數目 fontstyle:文字型別(斜體、粗體...))
int Indentation(String fontname, int fontsize, int fontnum, FontStyle fontstyle)
{
    Graphics gp = this.CreateGraphics();
    gp.PageUnit = GraphicsUnit.Point;
    SizeF size = gp.MeasureString("字", new Font(fontname, fontsize * 0.75F, fontstyle));
    return (int)size.Width * fontnum * 10;
}

範例:建立段落

var paragraph = doc.CreateParagraph();
paragraph.Alignment = ParagraphAlignment.CENTER; //字型居中
var run = paragraph.CreateRun();
run.IsBold = true;
run.SetText(contend);
run.FontSize = 28;
run.SetFontFamily("黑體", FontCharRange.None); //設定黑體
//控制段落與其他元素的上下距離
paragraph.SpacingBeforeLines = 20;//上方距離
paragraph.SpacingAfterLines = 20;//下方距離

換頁(本頁未滿直接寫下一頁)

paragraph = doc.CreateParagraph();
paragraph.CreateRun().AddBreak(BreakType.PAGE);

文書處理

  • doc.Paragraphs 獲取到檔案裡的所有的段落物件;
  • para.ParagraphText 獲取段落的文字資料;
  • para.ReplaceText(要被替換的文字,替換文字) 替換段落的文字(模板能實現的關鍵)

4、表格處理

doc.Tables 獲取檔案裡的所有的表格物件;//doc.Tables獲取的只是Word中最外層的表格,不包含巢狀內層的。 
cell.Tables;//獲取巢狀單元格可使用 
row.Rows //獲取表格所有行; 
row.GetTableICells() ;//獲取表格行的所有單元格; 
獲取到單元格之後就可以獲取單元格里的文欄位落(Paragraphs)並且進行文字替換

建立表格

var table = doc.CreateTable(行數, 列數);
table.Width = 5000;

控制表格中列寬(這裡需要注意,只設定一行的列寬一旦插入文字就會使設定的列寬失效,所以要把每一個單元格都要設定上)

for (int r = 0; r < 8; r++)
{
      SetCellWith(table.GetRow(r).GetCell(0), "600");
      SetCellWith(table.GetRow(r).GetCell(1), "1500");
      SetCellWith(table.GetRow(r).GetCell(2), "1500");
      SetCellWith(table.GetRow(r).GetCell(3), "600");
 }

設定表格中單元格豎直居中

var rowcell = table.GetRow(r).GetCell(c);
rowcell.SetVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);

設定單元格內容

//table中的文字格式設定
var para = new CT_P();
var pCell = new XWPFParagraph(para, table.Body);
pCell.Alignment = paragraphAlignment; //字型居中
pCell.VerticalAlignment = TextAlignment.CENTER; //字型居中

var r1c1 = pCell.CreateRun();
r1c1.SetText(setText);
r1c1.FontSize = 11;
r1c1.SetFontFamily("宋體", FontCharRange.None); //設定雅黑字型
pCell.SpacingAfterLines = 40;
pCell.SpacingBeforeLines = 40;
//放入單元格
table.GetRow(4).GetCell(1).SetParagraph(pCell);

表格中換行

var run= paragraph.CreateRun();
run.SetText(contends[i]);
run.FontSize = 11;
run.SetFontFamily("宋體", FontCharRange.None); 
run.AddBreak(BreakType.TEXTWRAPPING);//換行

合併單元格

table.GetRow(rowIndex).MergeCells(fromCol, toCol);//合併列

水平合併行單元格

CT_Tc cttcofRowThird = cell.GetCTTc();
CT_TcPr ctProfRowThird = cttcofRowThird.AddNewTcPr();
ctProfRowThird.gridSpan = new CT_DecimalNumber();
ctProfRowThird.gridSpan.val = num.ToString();//合併num列

合併行、垂直合併列單元格

public void MYMergeRows(XWPFTable table, int fromRow, int toRow, int colIndex)
{
    for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++)
    {
        XWPFTableCell rowcell = table.GetRow(rowIndex).GetCell(colIndex);
        rowcell.SetVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
        CT_Tc cttc = rowcell.GetCTTc();
        CT_TcPr ctTcPr = cttc.tcPr;
        if (ctTcPr == null)
        {
            ctTcPr = cttc.AddNewTcPr();
        }

        if (rowIndex == fromRow)
        {
            // The first merged cell is set with RESTART merge value
            ctTcPr.AddNewVMerge().val = ST_Merge.restart;
        }
        else
        {
            // Cells which join (merge) the first one, are set with CONTINUE
            ctTcPr.AddNewVMerge().val = ST_Merge.@continue;//繼續合併行
        }
        ctTcPr.AddNewVAlign().val = ST_VerticalJc.center;//垂直
    }
}

5、頁首頁尾處理

XWPFDocument doc = new XWPFDocument();
doc.Document.body.sectPr = new CT_SectPr();
CT_SectPr m_SectPr = doc.Document.body.sectPr;

//建立頁首
CT_Hdr m_Hdr = new CT_Hdr();
CT_P m_P = m_Hdr.AddNewP();
m_P.AddNewR().AddNewT().Value = "頁首內容值";
m_P.AddNewPPr().AddNewJc().val = ST_Jc.center;// 頁首居中
                                                //建立頁首關係(headern.xml)
XWPFRelation Hrelation = XWPFRelation.HEADER;
XWPFHeader m_h = (XWPFHeader)doc.CreateRelationship(Hrelation, XWPFFactory.GetInstance(), doc.HeaderList.Count + 1);
doc.CreateFootnotes();

//設定頁首
m_h.SetHeaderFooter(m_Hdr);
CT_HdrFtrRef m_HdrFtr = m_SectPr.AddNewHeaderReference();
m_h.GetRelationById(m_HdrFtr.id);

//建立頁尾
CT_Ftr m_ftr = new CT_Ftr();
CT_P m_fP = m_ftr.AddNewP();
m_fP.AddNewR().AddNewT().Value = "頁尾內容值";
m_fP.AddNewPPr().AddNewJc().val = ST_Jc.center;// 頁首居中
                                                //建立頁尾關係(footern.xml)
XWPFRelation Frelation = XWPFRelation.FOOTER;
XWPFFooter m_f = (XWPFFooter)doc.CreateRelationship(Frelation, XWPFFactory.GetInstance(), doc.FooterList.Count + 1);

//設定頁尾
m_f.SetHeaderFooter(m_ftr);
m_HdrFtr = m_SectPr.AddNewFooterReference();
m_HdrFtr.type = ST_HdrFtr.@default;
m_f.GetRelationById(m_HdrFtr.id);

三、綜合範例

CT_SectPr srcpr = new CT_SectPr();
//設定A4紙縱向,如果要橫向,兩個值調換即可
srcpr.pgSz.w = (ulong)11906;
srcpr.pgSz.h = (ulong)16838;

XWPFDocument doc = new XWPFDocument();
doc.Document.body.sectPr = srcpr;
//輸出標題
XWPFParagraph ptitle = doc.CreateParagraph();
ptitle.Alignment = ParagraphAlignment.CENTER;
XWPFRun titlerun = ptitle.CreateRun(); //向該段落中新增文字
titlerun.SetText("標題");
titlerun.IsBold = true;
titlerun.FontFamily = "華文行楷";
titlerun.FontSize = 30;
titlerun.SetColor("blue");

//輸出一個段落
XWPFParagraph p2 = doc.CreateParagraph();
p2.Alignment = ParagraphAlignment.CENTER;
p2.IndentationFirstLine = (int)100; //首行縮排
XWPFRun r2 = p2.CreateRun();
r2.SetText(string.Format("生成時間:{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm")));
r2.FontSize = 15;
titlerun.FontFamily = "宋體";

StringBuilder sb = new StringBuilder();
using (FileStream stream = File.OpenRead("simple.docx"))
{
    XWPFDocument docx = new XWPFDocument(stream);

    //頁首
    foreach (XWPFHeader xwpfHeader in docx.HeaderList)
    {
        sb.AppendLine(string.Format("{0}", new string[] { xwpfHeader.Text }));
    }

    //頁尾

    foreach (XWPFFooter xwpfFooter in docx.FooterList)
    {
        sb.AppendLine(string.Format("{0}", new string[] { xwpfFooter.Text }));
    }

    //讀取段落
    foreach (var para in docx.Paragraphs)
    {
        string text = para.ParagraphText; //獲得文字
        var runs = para.Runs;
        // string styleid = para.Style;
        for (int i = 0; i < runs.Count; i++)
        {
            var run = runs[i];
            text = run.ToString(); //獲得run的文字
            sb.Append(text + ",");
        }
    }
    //讀取表格
    foreach (XWPFTable table in docx.Tables)
    {
        //迴圈表格行
        foreach (XWPFTableRow row in table.Rows)
        {
            foreach (XWPFTableCell cell in row.GetTableCells())
            {
                sb.Append(cell.GetText());
            }
        }
    }

    //讀取圖片
    foreach (XWPFPictureData pictureData in docx.AllPictures)
    {
        string picExtName = pictureData.SuggestFileExtension();
        string picFileName = pictureData.FileName;
        byte[] picFileContent = pictureData.Data;

        string picTempName = string.Format(Guid.NewGuid().ToString() + "_" + picFileName + "." + picExtName);

        using (FileStream fs = new FileStream(picTempName, FileMode.Create, FileAccess.Write))
        {
            fs.Write(picFileContent, 0, picFileContent.Length);
            fs.Close();
        }

        sb.AppendLine(picTempName);
    }

    Console.WriteLine(sb.ToString());
}

FileStream out1 = new FileStream("simple.docx", FileMode.Create);
doc.Write(out1);
out1.Close();

四、參考

Word與Excel字號對照表

到此這篇關於C#使用NPOI對word進行讀寫的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com