質問

I have a GridView and I want to export it in Word document using open XML table

var dt = FunctionThatReturnDataTable(id);            
var gd = new GridView
             {
                DataSource = dt,
                AutoGenerateColumns = true
             };

I created a word document and inserted one paragraph inside, now i want to add my gridview below

using (var myDoc = WordprocessingDocument.Create(@"c:test.doc",
                                    WordprocessingDocumentType.Document))
{                    
  MainDocumentPart mainPart = myDoc.AddMainDocumentPart();
  mainPart.Document = new Document();
  var body = new Body();
  var p = new Paragraph(new ParagraphProperties(
             new Justification() { Val = JustificationValues.Center }), 
                           new Run(new Text("Some Text")));
  body.Append(p);
  mainPart.Document.Append(body);
  mainPart.Document.Save();
}
役に立ちましたか?

解決

I can think of two different approaches to export a ASP.Net GridView to a word document:

The first approach renders the HTML of the GridView control into a memory stream and then uses the openxml altChunk element to import the generated HTML into the word document. In short the altChunk markup element instructs MS Word to import content (e.g. HTML) into the document. For an example, see the following code:

...

var p = new Paragraph(new ParagraphProperties(
         new Justification() { Val = JustificationValues.Center }), 
                       new Run(new Text("Some Text")));
body.Append(p);
mainPart.Document.Append(body);

// Add table to word document using alt chunk element.  
AddTableUsingAltChunk(gv, mainPart);

...

public static void AddTableUsingAltChunk(GridView gv, MainDocumentPart mainPart)
{
  MemoryStream ms = new MemoryStream();
  StreamWriter sw = new StreamWriter(ms, Encoding.UTF8);

  using (HtmlTextWriter htw = new HtmlTextWriter(sw))
  {
    gv.RenderControl(htw);  // Render HTML of GridView
    htw.Flush();

    string altChunkId = "myChunkId";

    // Create alternative format import part.
    AlternativeFormatImportPart formatImportPart = 
     mainPart.AddAlternativeFormatImportPart(
        AlternativeFormatImportPartType.Xhtml, altChunkId);
    ms.Seek(0, SeekOrigin.Begin);

    // Feed HTML data into format import part (chunk).
    formatImportPart.FeedData(ms);
    AltChunk altChunk = new AltChunk();
    altChunk.Id = altChunkId;    

    // Append chunk.
    mainPart.Document.Body.Append(altChunk);    
  }
}

The second approach is more complex. We use the classes provided by the openxml SDK to build the table. Please see the following code and the inline comments for further explanation.

var dt = FunctionThatReturnDataTable(id)

...

var p = new DocumentFormat.OpenXml.Wordprocessing.Paragraph(
  new DocumentFormat.OpenXml.Wordprocessing.ParagraphProperties(
           new Justification() { Val = JustificationValues.Center }),
                         new DocumentFormat.OpenXml.Wordprocessing.Run(new Text("Some Text")));
body.Append(p);
mainPart.Document.Append(body);

mainPart.Document.Body.Append(CreateTable(dt));    

...

// Creates an open xml table from the provided data table.
public static Table CreateTable(System.Data.DataTable dt)
{
  Table table = new Table();

  TableProperties tableProperties = new TableProperties();
  TableStyle tableStyle = new TableStyle() { Val = "MyStyle" };

  TableWidth tableWidth = new TableWidth() 
   { 
     Width = "0", 
     Type = TableWidthUnitValues.Auto 
   };
  TableLook tableLook = new TableLook() { Val = "04A0" };

  tableProperties.Append(tableStyle);
  tableProperties.Append(tableWidth);
  tableProperties.Append(tableLook);

  TableGrid tableGrid = new TableGrid();

  // Calculate column width in twentieths of a point (same width for every column).
  // 595=A4 paper width in points.
  int colWidth = (int)((595 / (float)dt.Columns.Count) * 20.0f);

  // Create columns
  foreach (DataColumn dc in dt.Columns)
  {
    tableGrid.Append(new GridColumn() { Width = colWidth.ToString() });
  }  

  table.Append(tableProperties);
  table.Append(tableGrid);

  // Create rows.
  foreach (DataRow dr in dt.Rows)
  {
    TableRow tableRow = new TableRow() 
     { 
       RsidTableRowAddition = "00C5307B", 
       RsidTableRowProperties = "00C5307B" 
     };

    // Create cells.
    foreach (object c in dr.ItemArray)
    {
      TableCell tableCell = new TableCell();

      TableCellProperties tableCellProperties = new TableCellProperties();

      TableCellWidth tableCellWidth = new TableCellWidth() 
        { 
          Width = colWidth.ToString(), 
          Type = TableWidthUnitValues.Dxa 
        };

      tableCellProperties.Append(tableCellWidth);

      Paragraph paragraph = new Paragraph() 
           { 
             RsidParagraphAddition = "00CC797A", 
             RsidRunAdditionDefault = "00CC797A" 
           };

      Run run = new Run();

      Text text = new Text();
      text.Text = c.ToString();

      run.Append(text);
      paragraph.Append(run);

      tableCell.Append(tableCellProperties);
      tableCell.Append(paragraph);

      tableRow.Append(tableCell);
    }
    table.Append(tableRow);
  }

  return table;
}

The resulting xml produced by the two approaches is rather different. Use a tool like the OpenXML SDK Productivity tool to view the generated xml. In the altChunk case you do not see the definition for the table in the generated xml.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top