【问题标题】:How to convert xml to excel file programmatically如何以编程方式将xml转换为excel文件
【发布时间】:2011-01-30 11:59:00
【问题描述】:

我有一个 xml 文档,其中包含我的项目的小数据,我想将我的 xml 转换为 excel 文件(microsoft office excel 2003 及更高版本)

如何以编程方式执行此操作?

【问题讨论】:

  • 你想将xml转换成xls吗?还是您想将数据从 xml 文件映射(以某种方式格式化)到 xls - 表。

标签: c# xml


【解决方案1】:

使用Microsoft.Office.Interop.Excel可以实现如下图:

首先声明这些必要的引用。

using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using Microsoft.Office.Tools.Excel;
using Microsoft.VisualStudio.Tools.Applications.Runtime;
using Excel = Microsoft.Office.Interop.Excel;
using Office = Microsoft.Office.Core;
using System.Diagnostics;
using Microsoft.Win32;

比创建excel应用如图:

Excel.Application excel2; // Create Excel app
Excel.Workbook DataSource; // Create Workbook
Excel.Worksheet DataSheet; // Create Worksheet
excel2 = new Excel.Application(); // Start an Excel app
DataSource = (Excel.Workbook)excel2.Workbooks.Add(1); // Add a Workbook inside
string tempFolder = System.IO.Path.GetTempPath(); // Get folder 
string FileName = openFileDialog1.FileName.ToString(); // Get xml file name

之后在循环中使用以下代码以确保复制 xml 文件中的所有项目

// Open that xml file with excel
DataSource = excel2.Workbooks.Open(FileName, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);
// Get items from xml file
DataSheet = DataSource.Worksheets.get_Item(1);
// Create another Excel app as object
Object xl_app;
xl_app = GetObj(1, "Excel.Application");
Excel.Application xlApp = (Excel.Application)xl_app;
// Set previous Excel app (Xml) as ReportPage
Excel.Application ReportPage = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
// Copy items from ReportPage(Xml) to current Excel object
Excel.Workbook Copy_To_Excel = ReportPage.ActiveWorkbook;

现在我们有一个名为 Copy_To_Excel 的 Excel 对象,其中包含 Xml 中的所有项目。 我们可以用我们想要的名称保存并关闭 Excel 对象..

Copy_To_Excel.Save("thePath\theFileName");
Copy_To_Excel.Close();

【讨论】:

  • 请简要说明您的回答。
  • 它在 excel 中打开文件名(传递 XML 文件路径),允许在数据复制完成后复制到 Copy_To_Excel 工作簿,关闭两者并完成。
  • 如果您不想使用这个,请从 GoogleCode 中查看:stackoverflow.com/questions/151005/…
  • 编辑您的答案以添加您的解释。这对人们发现它并试图弄清楚发生了什么事情会更有帮助。
  • 什么是GetObj?
【解决方案2】:

如果您可以控制生成的 XML,只需生成一个 XML 电子表格文件(Excel 2002 和 2003 的 XML 文件标准)。

这些在 Excel 中本地打开,无需更改扩展名。 (要在 Excel 中默认打开,文件扩展名 XML 应设置为使用“XML 编辑器”打开,这是一个 Office 应用程序,可根据需要将 XML 文件路由到 Excel、Word、PowerPoint、InfoPath 或您的外部 XML 编辑器。这是安装 Office 时的默认映射,但对于某些用户,尤其是在文本编辑器中编辑 XML 文件的开发人员来说,它可能不合适。)

或者,使用 NPOI 库生成本机 (97/2000 BIFF/XLS) Excel 文件而不是 XML。

【讨论】:

  • 是的,用 excel 打开 xml 是可以的,但我想将我的 xml 文件作为一个 excel 文件,在其中我可以在 excel 小宏上进行编写。
【解决方案3】:

您甚至可以将 XML 文件读取为字符串,并使用正则表达式读取标签之间的内容并创建 CSV 文件或使用 xpath 表达式读取 XML 文件数据并导出到 CSV 文件。

【讨论】:

  • 你甚至可以编写一个 XSLT 来将 XML 转换为 CSV
【解决方案4】:

我知道从基于 xml 的电子表格到 xls/xlsx 的基于代码的转换没有简单的方法。但是您可能会查看Microsoft Open Xml SDK,它可以让您使用 xlsx。您可能会构建 xlsx 电子表格并将其与您的数据一起提供。在 open-xml SDK 的层面上,这就像构建 xml 文件。

【讨论】:

    【解决方案5】:

    1.将xml文件填充到数据集中,
    2.在asp.net中通过以下方法将数据集转换为excel

    这些都是非常简单的方法。

      public static void Convert(System.Data.DataSet ds, System.Web.HttpResponse response)
        {
            //first let's clean up the response.object
            response.Clear();
            response.Charset = "";
            //set the response mime type for excel
            response.ContentType = "application/vnd.ms-excel";
            //create a string writer
            System.IO.StringWriter stringWrite = new System.IO.StringWriter();
    
    
            //create an htmltextwriter which uses the stringwriter
            System.Web.UI.HtmlTextWriter htmlWrite = new System.Web.UI.HtmlTextWriter(stringWrite);
            //instantiate a datagrid
            System.Web.UI.WebControls.DataGrid dg = new System.Web.UI.WebControls.DataGrid();
            //set the datagrid datasource to the dataset passed in
            dg.DataSource = ds.Tables[0];
            //bind the datagrid
            dg.DataBind();
    
    
            //tell the datagrid to render itself to our htmltextwriter
            dg.RenderControl(htmlWrite);
            //all that's left is to output the html
            response.Write(stringWrite.ToString());
            response.End();
        }
    

    【讨论】:

      【解决方案6】:

      对于数组元素用','逗号分隔并重复使用相同的列名

      1) XML 函数

      public static class XMLFunctions
      {       
          public static List<Tuple<string, string>> GetXMlTagsAndValues(string xml)
          {
              var xmlList = new List<Tuple<string, string>>();
      
              var doc = XDocument.Parse(xml);
      
              foreach (var element in doc.Descendants())
              {
                  // we don't care about the parent tags
                  if (element.Descendants().Count() > 0)
                  {
                      continue;
                  }
      
                  var path = element.AncestorsAndSelf().Select(e => e.Name.LocalName).Reverse();
                  var xPath = string.Join("/", path); 
      
                  xmlList.Add(Tuple.Create(xPath, element.Value));
              }
      
              return xmlList;
          }
      
          public static System.Data.DataTable CreateDataTableFromXmlFile(string xmlFilePath)
          {
              System.Data.DataTable Dt = new System.Data.DataTable();
              string input = File.ReadAllText(xmlFilePath);
      
              var xmlTagsAndValues = GetXMlTagsAndValues(input);
              var columnList = new List<string>();
      
              foreach(var xml in xmlTagsAndValues)
              {
                  if(!columnList.Contains(xml.Item1))
                  {
                      columnList.Add(xml.Item1);
                      Dt.Columns.Add(xml.Item1, typeof(string));
                  }                    
              }
      
              DataRow dtrow = Dt.NewRow();
              var columnList2 = new Dictionary<string, string>(); 
      
              foreach (var xml in xmlTagsAndValues)
              {
                  if (!columnList2.Keys.Contains(xml.Item1))
                  {
                      dtrow[xml.Item1] = xml.Item2;
                      columnList2.Add(xml.Item1, xml.Item2);
                  }
                  else
                  {   // Here we are using the same column but appending the next value
                      dtrow[xml.Item1] = columnList2[xml.Item1] + "," + xml.Item2;
      
                      columnList2[xml.Item1] = columnList2[xml.Item1] + "," + xml.Item2;
                  }
      
              }
      
              Dt.Rows.Add(dtrow);
      
              return Dt;
          }
      }
      

      2) 完整的 Excel 类

      using Microsoft.Office.Interop.Excel;
      using _Excel = Microsoft.Office.Interop.Excel;
      
      public class Excel 
      {
          string path = "";
          Application excel = new _Excel.Application();
          Workbook wb;
          Worksheet ws;
          public Range xlRange;
      
          static bool saveChanges = false;
          static int excelRow = 0;
          static List<string> columnHeaders = new List<string>();    
      
          public Excel(string path, int Sheet = 1)
          {
              this.path = path;
              wb = excel.Workbooks.Open(path);
              ws = wb.Worksheets[Sheet];
              xlRange = ws.UsedRange;
              excelRow = 0;
              columnHeaders = new List<string>();
          }
      
          public void SaveFile(bool save = true)
          {
              saveChanges = save;
          }
      
          public void Close()
          {
              wb.Close(saveChanges);
              System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);
              excel.Quit();
          }                      
      
          public void XMLToExcel(string xmlFilePath)
          {
              var dt = XMLFunctions.CreateDataTableFromXmlFile(xmlFilePath);
              AddDataTableToExcel(dt);
          }
      
          public void AddDataTableToExcel(System.Data.DataTable table)
          {       
              // Creating Header Column In Excel
              for (int i = 0; i < table.Columns.Count; i++)   
              {
                  if (!columnHeaders.Contains(table.Columns[i].ColumnName))
                  {
                      ws.Cells[1, columnHeaders.Count() + 1] = table.Columns[i].ColumnName;
                      columnHeaders.Add(table.Columns[i].ColumnName);
                  }
              } 
      
              // Get the rows
              for (int k = 0; k < table.Columns.Count; k++)
              {
                  var columnNumber = columnHeaders.FindIndex(x => x.Equals(table.Columns[k].ColumnName));
      
                  ws.Cells[excelRow + 2, columnNumber + 1] = table.Rows[0].ItemArray[k].ToString();
              }
      
              excelRow++; 
              SaveFile(true);         
          }
      }
      

      3) 调用它

      var excel = new Excel(excelFilename);
      
      foreach (var filePath in files)
      {   
          excel.XMLToExcel(filePath); 
      }
      
      excel.Close();
      

      对于具有附加递增列名的数组元素(例如 column_2)

      从 XmlFile 重做创建数据表

      public static System.Data.DataTable CreateDataTableFromXmlFile(string xmlFilePath)
      {
          System.Data.DataTable Dt = new System.Data.DataTable();
      
          string input = File.ReadAllText(xmlFilePath);
      
          var xmlTagsAndValues = GetXMlTagsAndValues(input);
          var columnList = new List<string>();
      
          foreach (var xml in xmlTagsAndValues)
          {
              if (!columnList.Contains(xml.Item1))
              {
                  columnList.Add(xml.Item1);
                  Dt.Columns.Add(xml.Item1, typeof(string));
              }                   
              else 
              {
                  var columnName = xml.Item1;
      
                  do
                  {
                      columnName = columnName.Increment();
                  } while (columnList.Contains(columnName));
      
                  columnList.Add(columnName);
                  Dt.Columns.Add(columnName, typeof(string));
      
              }
          }
      
          DataRow dtrow = Dt.NewRow();
          var columnList2 = new Dictionary<string, string>();  
      
          foreach (var xml in xmlTagsAndValues)
          {
              if (!columnList2.Keys.Contains(xml.Item1))
              {
                  dtrow[xml.Item1] = xml.Item2;
                  columnList2.Add(xml.Item1, xml.Item2);
              }
              else
              {
                  var columnName = xml.Item1;
      
                  do
                  {
                      columnName = columnName.Increment();
                  } while (columnList2.Keys.Contains(columnName));
      
                  dtrow[columnName] = xml.Item2;
                  columnList2[columnName] = xml.Item2;
              }           
          }
      
          Dt.Rows.Add(dtrow);
      
          return Dt;
      }
      

      字符串扩展

      public static class StringExtensions
      {
          public static string Increment(this string str)
          {
              if (!str.Contains("_"))
              {
                  str += "_2";
                  return str;
              }
      
              var number = int.Parse(str.Substring(str.LastIndexOf('_') + 1));            
      
              var stringBefore = StringFunctions.GetUntilOrEmpty(str, "_");            
      
              return $"{stringBefore}_{++number}";
          }
      }
      

      使用GetUntilOrEmpty

      【讨论】:

        【解决方案7】:

        How to open an XML file in Excel 2003.

        简而言之,您只需使用 FileOpen 即可打开它。然后,当您选择 XML 文件时,系统会提示您选择以下方法之一来导入 XML 数据:

        • 作为 XML 列表
        • 作为只读工作簿
        • 使用 XML 源任务窗格

        【讨论】:

        • 我知道,谢谢;但我需要一个代码来做到这一点,如下所述。我发现 msdn 文档很旧,而且太复杂而无法理解 :(
        【解决方案8】:

        您不能简单地在 Excel 中打开它吗?我以为 Excel 可以识别后缀 XML?

        【讨论】:

        • xml文件可以在excel中轻松打开。通过程序转换xml文件的原因是更普通地在excel中打开工作表中的xml文件。要不是说这里的人是您的 xml 文档并不容易,请用 excel 打开它。更改文件扩展名也不行。
        • 聚会迟到了,但我不确定我是否理解你的解释。我想你是说你想用代码来做。但我不知道你所说的“转换的原因是打开......更普通”。我不知道那是什么意思。
        猜你喜欢
        • 1970-01-01
        • 2010-10-27
        • 1970-01-01
        • 1970-01-01
        • 2010-09-07
        • 2020-05-06
        • 1970-01-01
        • 1970-01-01
        • 2013-02-15
        相关资源
        最近更新 更多