using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DocumentFormat.OpenXml.Drawing.Wordprocessing;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
namespace ReportDoc
{
/// <summary>
/// 作者:HaoZhenHu
/// </summary>
public class Report
{
/// <summary>
/// 用于获取内容控件中指定的文档表
/// </summary>
/// <param name="oxe">内容控件</param>
/// <param name="tag">标签</param>
/// <returns></returns>
public static Table DOC_TAB_GetTable(ref OpenXmlElement _oxe, string _tag)
{
SdtBlock _tBlock = _oxe.Descendants <SdtBlock>().Where(el => el.SdtProperties.GetFirstChild<Tag>().Val == _tag).Single();
return _tBlock.Descendants<Table>().Single<Table>();
}
/// <summary>
/// 获取内容控件表中的行数
/// </summary>
/// <param name="_tb">文档表对象</param>
/// <returns></returns>
public static int DOC_TAB_GetTableRowCount(Table _tb)
{
return _tb.Elements<TableRow>().Count();
}
/// <summary>
/// 删除指定索引的行
/// </summary>
/// <param name="_tb">文档表对象</param>
/// <param name="_index">删除行的索引</param>
/// <returns></returns>
public static bool DOC_TAB_DeleteTableRow(ref Table _tb, int _index)
{
if (!(_index >= 0 && _index < _tb.Elements<TableRow>().Count()))
{
return false;
}
try
{
_tb.RemoveChild(_tb.Elements<DocumentFormat.OpenXml.Wordprocessing.TableRow>().ElementAt(_index));
}
catch (Exception e)
{
throw new Exception(e.Message);
}
return true;
}
/// <summary>
/// 删除指定行 (重载)
/// </summary>
/// <param name="_tb">文档表</param>
/// <param name="_tableRow">文档表行</param>
/// <returns></returns>
public static bool DOC_TAB_DeleteTableRow(ref Table _tb, ref TableRow _tableRow)
{
try
{
_tb.RemoveChild(_tableRow);
return true;
}
catch
{
return false;
}
}
/// <summary>
/// 返回指定索引的行
/// </summary>
/// <param name="_tb">文档表对象</param>
/// <param name="_index">指定行的索引</param>
/// <returns></returns>
public static TableRow DOC_TAB_GetTableRow(ref Table _tb, int _index)
{
try
{
return _tb.Elements<TableRow>().ElementAt(_index);
}
catch (Exception e)
{
throw new Exception(e.Message);
}
}
/// <summary>
/// 返回复制后的文档表行
/// </summary>
/// <param name="_tableRow">要被复制的文档表行</param>
/// <returns></returns>
public static TableRow DOC_TAB_CloneTableRow(TableRow _tableRow)
{
return (TableRow)_tableRow.Clone();
}
/// <summary>
/// 返回复制后的文档表行 (重载)
/// </summary>
/// <param name="_tb">文档表</param>
/// <param name="_index">行所在索引</param>
/// <returns></returns>
public TableRow DOC_TAB_CloneTableRow(Table _tb, int _index)
{
return (TableRow)_tb.Elements<TableRow>().ElementAt(_index).Clone();
}
/// <summary>
/// 向文档中指定的单元格添加数据
/// </summary>
/// <param name="_content">要添加的数据</param>
/// <param name="_tableRow">文档行</param>
/// <param name="_index">单元格的索引</param>
public static void DOC_TAB_FillCellData(string _content, ref TableRow _tableRow, int _index)
{
TableCell _tableCell = _tableRow.Elements<TableCell>().ElementAt(_index);
string[] _contentLine = System.Text.RegularExpressions.Regex.Split(_content, @"/r/n");
DOC_TAB_ClearTextTableCell(ref _tableCell);
for (int i = 0; i < _contentLine.Length; i++)
{
string _curCellData = _contentLine[i];
//如果是第一行,则直接填充
if (0 == i)
{
if (_tableCell.Elements<Paragraph>().Count() > 0)
{
Paragraph _newParagraph = _tableCell.Elements<Paragraph>().Last();
if (_newParagraph.Elements<ParagraphProperties>().Count() > 0)
{
ParagraphProperties _paragraphProper = _newParagraph.Elements<ParagraphProperties>().First();
RunProperties _newRunProper = new RunProperties();
if (_paragraphProper.Elements<ParagraphMarkRunProperties>().Count() > 0)
{
ParagraphMarkRunProperties _paraMarkRunProper = _paragraphProper.Elements<ParagraphMarkRunProperties>().First();
for (int j = 0; j < _paraMarkRunProper.Elements().Count(); j++)
{
_newRunProper.Append(_paraMarkRunProper.Elements().ElementAt(j).CloneNode(true));
}
}
else
{
_newRunProper.Append(new RunFonts() { Hint = FontTypeHintValues.EastAsia });
}
_newParagraph.Append(new Run(_newRunProper, new Text(_curCellData) { Space = "preserve" }));
}
else
{
_newParagraph.Append(new ParagraphMarkRunProperties(new RunFonts(){ Hint = FontTypeHintValues.EastAsia }));
_newParagraph.Append(new Run(new RunProperties(new RunFonts() { Hint = FontTypeHintValues.EastAsia }), new Text(_curCellData) { Space = "preserve" }));
}
}
else
{
Paragraph _newParagraph = new Paragraph();
_newParagraph.Append(new ParagraphMarkRunProperties(new RunFonts().EastAsia));
_newParagraph.Append(new DocumentFormat.OpenXml.Wordprocessing.Run(new RunProperties(new RunFonts() { Hint = FontTypeHintValues.EastAsia }), new Text(_curCellData) { Space = "preserve" }));
}
}
else
{
Paragraph _paragraph = _tableCell.Elements<Paragraph>().Last();
Paragraph _newParagraph = (Paragraph)_paragraph.Clone();
DocumentFormat.OpenXml.Wordprocessing.Run _newRun = _newParagraph.Elements<DocumentFormat.OpenXml.Wordprocessing.Run>().Last();
DocumentFormat.OpenXml.Wordprocessing.Text _newText = _newRun.Elements<DocumentFormat.OpenXml.Wordprocessing.Text>().Last();
_newText.Text = _curCellData;
_tableCell.Append(_newParagraph);
}
}
}
/// <summary>
/// 在指定行后面添加新行
/// </summary>
/// <param name="_newRow">新行</param>
/// <param name="_tb">文档表</param>
/// <param name="_index">行索引</param>
public static void DOC_TAB_InsertRowAfter(TableRow _newRow, ref Table _tb, int _index)
{
TableRow _tableRow = _tb.Elements<TableRow>().ElementAt(_index);
_tb.InsertAfter<TableRow>(_newRow, _tableRow);
}
/// <summary>
/// 在指定行前面添加新行
/// </summary>
/// <param name="_newRow">新行</param>
/// <param name="_tb">文档表</param>
/// <param name="_index">行索引</param>
public static void DOC_TAB_InsertRowBefore(TableRow _newRow, ref Table _tb, int _index)
{
TableRow _tableRow = _tb.Elements<TableRow>().ElementAt(_index);
_tb.InsertBefore<TableRow>(_newRow, _tableRow);
}
/// <summary>
/// 清除单元格中的内容,但保留其格式
/// </summary>
/// <param name="_tableCell">单元格</param>
public static void DOC_TAB_ClearTextTableCell(ref TableCell _tableCell)
{
for (int i = _tableCell.Elements<Paragraph>().Count()-2; i >=0 ; i--)
{
_tableCell.Elements<Paragraph>().ElementAt(i).Remove();
}
Paragraph _paragraph = _tableCell.Elements<Paragraph>().Single();
foreach (Run _run in _paragraph.Elements<Run>())
{
_run.RemoveAllChildren();
}
}
/// <summary>
/// 用于插入文本内容
/// </summary>
/// <param name="_oxe">要填充内容的节点</param>
/// <param name="_content">填充的内容</param>
public static void DOC_TEXT_FillData(ref OpenXmlElement _oxe, string _content)
{
string _eType = _oxe.GetType().Name;
switch (_eType)
{
case "SdtBlock":
Paragraph _paragraph = (Paragraph)_oxe.Descendants<Paragraph>().First().Clone();
Run _run = (Run)_paragraph.Elements<Run>().First().Clone();
_run.RemoveAllChildren<Text>();
_run.AppendChild<Text>(new Text(_content));
_paragraph.AppendChild<Run>(_run);
_oxe.RemoveAllChildren<Paragraph>();
_oxe.AppendChild<Paragraph>(_paragraph);
break;
case "SdtRun":
SdtRun _sdtRun = (SdtRun)_oxe;
_sdtRun.SdtProperties.RemoveAllChildren<SdtPlaceholder>();
RunProperties _runPro = (RunProperties)_sdtRun.Elements<RunProperties>().Single().Clone();
Text _runText = new Text(_content);
Run _runAnother = _sdtRun.SdtContentRun.Elements<Run>().Single();
_runAnother.RemoveAllChildren();
_runAnother.AppendChild(_runPro);
_runAnother.AppendChild(_runText);
break;
case "Run":
_oxe.RemoveAllChildren();
_oxe.AppendChild(new Text(_content));
break;
}
}
}
}
应用:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using ReportDoc;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System.IO;
namespace DocDemo
{
public partial class _Default : System.Web.UI.Page
{
public struct TestData
{
public int ID;
public string Name;
}
protected void Page_Load(object sender, EventArgs e)
{
List<TestData> _testDataList = new List<TestData>();
TestData _myData;
_myData.ID = 1;
_myData.Name = "xiaohulove/r/ny";
_testDataList.Add(_myData);
_myData.ID = 2;
_myData.Name = "/r/nisxiaohu'shoney";
_testDataList.Add(_myData);
WordprocessingDocument _wordPoc = null;
try
{
_wordPoc = WordprocessingDocument.Open(Server.MapPath("./testDoc.docx"), true);
MainDocumentPart _mainDocumentPart = _wordPoc.MainDocumentPart;
OpenXmlElement _oxe = _mainDocumentPart.Document.Body;
//_oxe.RemoveAllChildren();
//Paragraph _paragraph = new Paragraph();
//Run _newRun = new Run();
//_paragraph.AppendChild<Run>(_newRun);
//OpenXmlElement _element = _paragraph.Elements<Run>().Single();
//Report.DOC_TEXT_FillData(ref _element, "aaaaaaa");
//_oxe.AppendChild<Paragraph>(_paragraph);
DocumentFormat.OpenXml.Wordprocessing.Table _myTable = Report.DOC_TAB_GetTable(ref _oxe, "vs");
//int count = _myTable.Elements<DocumentFormat.OpenXml.Wordprocessing.TableRow>().Count();
int count = Report.DOC_TAB_GetTableRowCount(_myTable);
DocumentFormat.OpenXml.Wordprocessing.TableRow _templateTRow = Report.DOC_TAB_GetTableRow(ref _myTable, 1);
for (int j = count - 1; j > 0; j--)
{
//_myTable.RemoveChild(_myTable.Elements<DocumentFormat.OpenXml.Wordprocessing.TableRow>().ElementAt(j));
Report.DOC_TAB_DeleteTableRow(ref _myTable, j);
}
int i = 0;
foreach (TestData _test in _testDataList)
{
DocumentFormat.OpenXml.Wordprocessing.TableRow _myRow = Report.DOC_TAB_CloneTableRow(_templateTRow);
Report.DOC_TAB_FillCellData(_test.ID.ToString(), ref _myRow, 0);
Report.DOC_TAB_FillCellData(_test.Name, ref _myRow, 1);
Report.DOC_TAB_InsertRowAfter(_myRow, ref _myTable, i);
i++;
}
}
catch
{
_wordPoc.Close();
GC.Collect();
Page.RegisterStartupScript("aaaaaaa", "<script>window.alert('wrong');</script>");
return;
}
_wordPoc.MainDocumentPart.Document.Save();
_wordPoc.Close();
GC.Collect();
}
}
}