Is there anyway to change the file extension on a csv download from mvcgrid? It downloads as .csv and i'd like .txt to stop my users from opening the contents in excel?
I can see there is a custom rendering engine, but that seems to offer file contents formats rather than the extension.
Thanks
Managed it via a customendering engine
using MVCGrid.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
namespace MVCGrid.Web.Models
{
public class TextExportEngine : IMVCGridRenderingEngine
{
public bool AllowsPaging
{
get { return false; }
}
public void PrepareResponse(HttpResponse httpResponse)
{
httpResponse.Clear();
httpResponse.ContentType = "text/comma-separated-values";
httpResponse.AddHeader("content-disposition", "attachment; filename=\"" + "export" + ".txt\"");
httpResponse.BufferOutput = false;
}
public void Render(MVCGrid.Models.RenderingModel model, MVCGrid.Models.GridContext gridContext, System.IO.TextWriter outputStream)
{
var sw = outputStream;
StringBuilder sbHeaderRow = new StringBuilder();
foreach (var col in model.Columns)
{
if (sbHeaderRow.Length != 0)
{
sbHeaderRow.Append(",");
}
sbHeaderRow.Append(Encode(col.Name));
}
sbHeaderRow.AppendLine();
sw.Write(sbHeaderRow.ToString());
foreach (var item in model.Rows)
{
StringBuilder sbRow = new StringBuilder();
foreach (var col in model.Columns)
{
var cell = item.Cells[col.Name];
if (sbRow.Length != 0)
{
sbRow.Append(",");
}
string val = cell.PlainText;
sbRow.Append(Encode(val));
}
sbRow.AppendLine();
sw.Write(sbRow.ToString());
}
}
private string Encode(string s)
{
if (String.IsNullOrWhiteSpace(s))
{
return "";
}
return s;
}
public void RenderContainer(MVCGrid.Models.ContainerRenderingModel model, System.IO.TextWriter outputStream)
{
}
}
}
and then adding the following to my grid definition
.AddRenderingEngine("tabs", typeof(TextExportEngine)
Related
I want to put a data from simple csv file into the records containing custom made class.
Here is my code:
using System;
using CsvHelper;
using System.IO; // for accessing the files
using System.Globalization;
using System.Linq; // to call a list enumerable
using CsvHelper.Configuration;
using CsvHelper.Configuration.Attributes;
namespace Reading_CSV_Files
{
class Program
{
static void Main(string[] args)
{
ReadCSVFile(#"C:\path_to_my_file\file.csv");
}
public static void ReadCSVFile(String filePath)
{
if (filePath == null)
{
return;
}
using (var streamReader = new StreamReader(filePath) )
{
using (var foodFileCSVReader = new CsvReader(streamReader,
CultureInfo.InvariantCulture))
{
//var records = foodFileCSVReader.GetRecords<dynamic>().ToList();
var records = foodFileCSVReader.GetRecords<Pizza>().ToList();
// replace dynamic type argument on our records
}
}
}
}
public class Pizza
{
// attributes
[Name("Name")]
public String Name { get; set; }
[Name("PLN_Cost")]
public double Price { get; set; }
}
}
The csv file looks like this:
Screenshot from csv file
The file was saved as comma separated. I found some advices with manual setting it up, but currently it says, this field is read-only.
CsvHelper.HeaderValidationException: Header with name 'Name'[0] was not found.
Header with name 'PLN_Cost'[0] was not found.
If the program is going to be using CSV files which might have a comma or semi-colon as the separator, you could read the first line and set the separator to either of those, like this:
using CsvHelper;
using CsvHelper.Configuration;
using CsvHelper.Configuration.Attributes;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
namespace ConsoleApp1
{
class Program
{
public class Pizza
{
// attributes
[Name("Name")]
public String Name { get; set; }
[Name("PLN_Cost")]
public decimal Price { get; set; }
public override string ToString()
{
return $"{Name} - {Price}";
}
}
public static List<Pizza> ReadCSVFile(String filePath)
{
if (!File.Exists(filePath))
{
return new List<Pizza>();
}
var sep = ";";
/* Check the header for the separator character to use. */
string headerLine = File.ReadLines(filePath).First();
if (headerLine?.IndexOf(',') >= 0) { sep = ","; }
using (var sr = new StreamReader(filePath))
{
var config = new CsvConfiguration(CultureInfo.CurrentCulture)
{
Delimiter = sep,
Encoding = Encoding.UTF8
};
using (var foodFileCSVReader = new CsvReader(sr, config))
{
return foodFileCSVReader.GetRecords<Pizza>().ToList();
}
}
}
static void Main(string[] args)
{
var pp = ReadCSVFile(#"C:\temp\PizzaPrices.csv");
Console.WriteLine(string.Join("\r\n", pp));
Console.ReadLine();
}
}
}
Note that it is better to use the decimal type for money instead of the double type.
You might need additional code to set the decimal separator to be used.
I have ASP.Net site. I have JSON string that need to exported to physical CSV file.
private String JsonToCsv(string jsonData, string delimiter)
{
try
{
StringWriter swObj = new StringWriter();
using (var csv = new CsvWriter(swObj))
{
csv.Configuration.SkipEmptyRecords = true;
csv.Configuration.WillThrowOnMissingField = false;
csv.Configuration.Delimiter = delimiter;
using (var dt = jsonStringToTable(jsonData))
{
foreach (DataColumn col in dt.Columns)
{
csv.WriteField(col.ColumnName);
}
csv.NextRecord();
foreach(DataRow row in dt.Rows)
{
for (var i = 0; i < dt.Columns.Count; i++)
{
csv.WriteField(row[i]);
}
csv.NextRecord();
}
}
}
return swObj.ToString();
}
catch (Exception ex)
{
//handle exception
return null;
}
}
private DataTable jsonStringToTable(string jsonContent)
{
DataTable dt = JsonConvert.DeserializeObject<DataTable>(jsonContent);
return dt;
}
public HttpResponseMessage ExportToCSV(string jsonData)
{
string csv = JsonToCsv(jsonData, ",");
HttpResponseMessage res = new HttpResponseMessage(HttpStatusCode.OK);
res.Content = new StringContent(csv);
res.Content.Headers.ContentType = new MediaTypeHeaderValue("text/csv");
res.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = "export.csv" };
return res;
}
But neither I am getting any exception nor CSV file is getting any data.
The Export.csv is located in the root folder.
How do I export the JSON & auto download the file??
It seems you do have an error, that you are suppressing in your catch.
Your first error is in that your jsonContent is not actually json. You have a variable assignment jsonContent = [...] in your sample. the section [...] is your actual json.
to handle that, you need only compose it better, by not having it assign to a variable (recommended approach), or handle instances here with jsonContent.Split(new [] {'='}).Last(). (a declarative vs imperative approach/strategy).
Also, you are attempting to deserialize into an incorrect type, for it does not reflect your json data structure.
although there are other manners to convert and process one string to another. I do agree the proper thing to do here is to deserialize your object (or not serialize beforehand - recommended).
I'm providing a sample Console Application for you to review two implementations of handle a JsonToCsv operation.
dynamic (imperative)
and providing a Type and using System.Reflection on that type. (declarative to the Json.Convert.DeserializeObject<T>() method, imperative afterward)
there is a dependency on NewtonSoft.Json Assembly (Install it via NuGet package) in this implementation; it reflects your provided code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Dynamic;
using System.Reflection;
using Newtonsoft;
namespace JsonToCsvTests
{
using Newtonsoft.Json;
using System.IO;
using System.Threading.Tasks;
class Program
{
static void Main(string[] args)
{
TestJsonToCsv();
Console.ReadLine();
}
static void TestJsonToCsv()
{
string jsonData = #"jsonData = [
{
""DocumentName"": ""Test Document"",
""ActionDate"": ""2015-09-25T16:06:25.083"",
""ActionType"": ""View"",
""ActionPerformedBy"": ""Sreeja SJ""
},
{
""DocumentName"": ""Test Document"",
""ActionDate"": ""2015-09-25T16:12:02.497"",
""ActionType"": ""View"",
""ActionPerformedBy"": ""Sreeja SJ""
},
{
""DocumentName"": ""Test Document"",
""ActionDate"": ""2015-09-25T16:13:48.013"",
""ActionType"": ""View"",
""ActionPerformedBy"": ""Sreeja SJ""
}]";
Console.WriteLine("...using System.Dynamic and casts");
Console.WriteLine();
Console.WriteLine(JsonToCsv(jsonData, ","));
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("...using a provided StrongType with System.Reflection.");
Console.WriteLine();
Console.WriteLine(JsonToCsv<JsonData>(jsonData, ","));
}
static private string JsonToCsv(string jsonContent, string delimiter)
{
var data = jsonStringToTable(jsonContent);
var headers = ((IEnumerable<dynamic>)((IEnumerable<dynamic>)data).First()).Select((prop) => prop.Name).ToArray();
var csvList = new List<string>
{
string.Join(delimiter, headers.Select((prop) => string.Format(#"""{0}""", prop)).ToArray())
};
var lines = ((IEnumerable<dynamic>)data)
.Select(row => row)
.Cast<IEnumerable<dynamic>>()
.Select((instance) => string.Join(delimiter, instance.Select((v) => string.Format(#"""{0}""", v.Value))))
.ToArray();
csvList.AddRange(lines);
return string.Join(Environment.NewLine, csvList );
}
static private string JsonToCsv<T>(string jsonContent, string delimiter) where T : class
{
var data = jsonStringToTable<T>(jsonContent);
var properties = data.First().GetType().GetProperties();
var lines = string.Join(Environment.NewLine,
string.Join(delimiter, properties.Select((propInfo) => string.Format(#"""{0}""", propInfo.Name))),
string.Join(Environment.NewLine, data.Select((row) => string.Join(delimiter, properties.Select((propInfo) => string.Format(#"""{0}""", propInfo.GetValue(row)))))));
return lines;
}
static private dynamic jsonStringToTable(string jsonContent)
{
var json = jsonContent.Split(new[] { '=' }).Last();
return JsonConvert.DeserializeObject<dynamic>(json);
}
static private IEnumerable<T> jsonStringToTable<T>(string jsonContent) where T : class
{
var json = jsonContent.Split(new[] { '=' }).Last();
return JsonConvert.DeserializeObject<IEnumerable<T>>(json);
}
public class JsonData
{
public string DocumentName { get; set; }
public DateTime ActionDate { get; set; }
public string ActionType { get; set; }
public string ActionPerformedBy { get; set; }
}
}
}
Console.Output
...using System.Dynamic and casts
"DocumentName","ActionDate","ActionType","ActionPerformedBy"
"Test Document","9/25/2015 4:06:25 PM","View","Sreeja SJ"
"Test Document","9/25/2015 4:12:02 PM","View","Sreeja SJ"
"Test Document","9/25/2015 4:13:48 PM","View","Sreeja SJ"
...using a provided StrongType with System.Reflection.
"DocumentName","ActionDate","ActionType","ActionPerformedBy"
"Test Document","9/25/2015 4:06:25 PM","View","Sreeja SJ"
"Test Document","9/25/2015 4:12:02 PM","View","Sreeja SJ"
"Test Document","9/25/2015 4:13:48 PM","View","Sreeja SJ"
This is what i use to generate CSV file on my ASP.NET Website
public static class CSVUtils
{
public static void AddCsvLine(bool isFrenchSeparator, StringBuilder csv, params object[] values)
{
foreach (var value in values)
{
csv.Append('"').Append(value).Append('"');
if (isFrenchSeparator)
{
csv.Append(';');
}
else
{
csv.Append(',');
}
}
csv.Append('\r'); // AppendLine() adds a double line break with UTF32Encoding
}
}
public FileContentResult ExportCSV()
{
StringBuilder csv = new StringBuilder();
CSVUtils.AddCsvLine(false, csv, "Field1", "Field2", "Field3");
CSVUtils.AddCsvLine(false, csv, "value1", "value2", "value3");
return this.File(new UTF32Encoding().GetBytes(csv.ToString()), "text/csv", "myfile.csv");
}
I basically call the ExportCSV action from my website, on a button click for example and it downloads the file. Make sure to clean your JSON beforehand from all coma otherwise it would mess your CSV file.
EDIT: Specifically for JSON, you'd also have to anti-slash every " otherwise it would mess the StringBuilder i guess
I have been searching the internet for days now and I was just wondering if anyone has done any work with exporting data to excel using MVC 3. I really need a good tutorial that has step-by-step instructions on how to export excel data using MVC 3 with C#. I have found plenty of articles but none of them seem to work with my existing database. I am just looking for some instruction on where to put methods etc. This tutorial http://stephenwalther.com/blog/archive/2008/06/16/asp-net-mvc-tip-2-create-a-custom-action-result-that-returns-microsoft-excel-documents.aspx
seems to be highly recommended on stack overflow. I have followed the article's instructions to the letter but I can't run the program because Visual studio is throwing an error on the return for method GenerateExcel1
This is where VS is saying I have an error
return this.Excel(db, db.iamp_mapping, "data.xls")
right now I am getting 2 error messages that say
Error 1 'DBFirstMVC.Controllers.PaController' does not contain a
definition for 'Excel' and the best extension method overload
'DBFirstMVC.CustomActionResults.ExcelControllerExtensions.Excel(System.Web.Mvc.Controller,
System.Data.Linq.DataContext, System.Linq.IQueryable, string)' has
some invalid arguments C:\Documents and Settings\lk230343\My
Documents\Visual Studio 2010\WebSites\DBFirstMVC
Saves\DBFirstMVC_CRUD_and_PAGING_done\DBFirstMVC\Controllers\PaController.cs 193 24 DBFirstMVC
Error 2 Argument 2: cannot convert from 'DBFirstMVC.Models.PaEntities'
to 'System.Data.Linq.DataContext' C:\Documents and
Settings\lk230343\My Documents\Visual Studio 2010\WebSites\DBFirstMVC
Saves\DBFirstMVC_CRUD_and_PAGING_done\DBFirstMVC\Controllers\PaController.cs 193 35 DBFirstMVC
Has anyone ever seen these errors before or have any idea on how I can fix them? I mean the excel method exists in ExcelControllerExtensions.cs and I thought I had made that assembly available to the PaController. Honestly, I have no idea why it is throwing an error on the return so any advice/discussion/help would be welcomed. I have included the code for the 3 files that I have been messing with but if you think I forgot to post one that is needed to diagnose this error let me know and I will post it. Thanks for your help!
PaController
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Web.UI.WebControls;
using System.Web;
using System.Web.Mvc;
using DBFirstMVC.Models;
using System.Data;
using PagedList;
using PagedList.Mvc;
using DBFirstMVC.Controllers;
using System.IO;
using DBFirstMVC;
using DBFirstMVC.CustomActionResults;
namespace DBFirstMVC.Controllers
{
public class PaController : Controller
{
private PaEntities db = new PaEntities();
//
// GET: /Pa/
public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)
{
ViewBag.CurrentSort = sortOrder;
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "PA desc" : "";
ViewBag.MPSortParm = sortOrder == "MP" ? "MP desc" : "MP asc";
ViewBag.IASortParm = sortOrder == "IA" ? "IA desc" : "IA asc";
if (Request.HttpMethod == "GET")
{
searchString = currentFilter;
}
else
{
page = 1;
}
ViewBag.CurrentFilter = searchString;
var IAMP = from p in db.iamp_mapping select p;
if (!String.IsNullOrEmpty(searchString))
{
IAMP = IAMP.Where(p => p.PA.ToUpper().Contains(searchString.ToUpper()));
}
switch (sortOrder)
{
case "Pa desc":
IAMP = IAMP.OrderByDescending(p => p.PA);
break;
case "MP desc":
IAMP = IAMP.OrderByDescending(p =>p.MAJOR_PROGRAM);
break;
case "MP asc":
IAMP = IAMP.OrderBy(p =>p.MAJOR_PROGRAM);
break;
case "IA desc":
IAMP = IAMP.OrderByDescending(p => p.INVESTMENT_AREA);
break;
case "IA asc":
IAMP = IAMP.OrderBy(p => p.INVESTMENT_AREA);
break;
default:
IAMP = IAMP.OrderBy(p => p.PA);
break;
}
int pageSize = 25;
int pageNumber = (page ?? 1);
return View(IAMP.ToPagedList(pageNumber, pageSize));
}
//
// GET: /Pa/Details/5
public ActionResult Details(int id)
{
return View();
}
//
// GET: /Pa/Create
public ActionResult Create()
{
return View();
}
//
// POST: /Pa/Create
[HttpPost]
public ActionResult Create(iamp_mapping IAMP)
{
try
{
using (var db = new PaEntities())
{
db.iamp_mapping.Add(IAMP);
db.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
//
// GET: /Pa/Edit/5
public ActionResult Edit(string id)
{
using (var db = new PaEntities())
{
return View(db.iamp_mapping.Find(id));
}
}
//
// POST: /Pa/Edit/5
[HttpPost]
public ActionResult Edit(string id, iamp_mapping IAMP)
{
try
{
using (var db = new PaEntities())
{
db.Entry(IAMP).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("");
}
}
catch
{
return View();
}
}
//
// GET: /Pa/Delete/5
public ActionResult Delete(string id)
{
using (var db = new PaEntities())
{
return View(db.iamp_mapping.Find(id));
}
}
//
// POST: /Pa/Delete/5
[HttpPost]
public ActionResult Delete(string id, iamp_mapping IAMP)
{
try
{
using (var db = new PaEntities())
{
var vIAMP = db.iamp_mapping.Find(id);
db.Entry(vIAMP).State = EntityState.Deleted;
db.SaveChanges();
return RedirectToAction("Index");
}
}
catch (Exception e)
{
throw (e);
//return View();
}
}
public ActionResult GenerateExcel1()
{
using (var db = new PaEntities())
{
return this.Excel(db, db.iamp_mapping, "data.xls");
}
}
}
}
ExcelResult.cs
using System;
using System.Web.Mvc;
using System.Data.Linq;
using System.Collections;
using System.IO;
using System.Web.UI.WebControls;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Drawing;
namespace DBFirstMVC
{
public class ExcelResult : ActionResult
{
private DataContext _dataContext;
private string _fileName;
private IQueryable _rows;
private string[] _headers = null;
private TableStyle _tableStyle;
private TableItemStyle _headerStyle;
private TableItemStyle _itemStyle;
public string FileName
{
get { return _fileName; }
}
public IQueryable Rows
{
get { return _rows; }
}
public ExcelResult(DataContext dataContext, IQueryable rows, string fileName)
: this(dataContext, rows, fileName, null, null, null, null)
{
}
public ExcelResult(DataContext dataContext, string fileName, IQueryable rows, string[] headers)
: this(dataContext, rows, fileName, headers, null, null, null)
{
}
public ExcelResult(DataContext dataContext, IQueryable rows, string fileName, string[] headers, TableStyle tableStyle, TableItemStyle headerStyle, TableItemStyle itemStyle)
{
_dataContext = dataContext;
_rows = rows;
_fileName = fileName;
_headers = headers;
_tableStyle = tableStyle;
_headerStyle = headerStyle;
_itemStyle = itemStyle;
// provide defaults
if (_tableStyle == null)
{
_tableStyle = new TableStyle();
_tableStyle.BorderStyle = BorderStyle.Solid;
_tableStyle.BorderColor = Color.Black;
_tableStyle.BorderWidth = Unit.Parse("2px");
}
if (_headerStyle == null)
{
_headerStyle = new TableItemStyle();
_headerStyle.BackColor = Color.LightGray;
}
}
public override void ExecuteResult(ControllerContext context)
{
// Create HtmlTextWriter
StringWriter sw = new StringWriter();
HtmlTextWriter tw = new HtmlTextWriter(sw);
// Build HTML Table from Items
if (_tableStyle != null)
_tableStyle.AddAttributesToRender(tw);
tw.RenderBeginTag(HtmlTextWriterTag.Table);
// Generate headers from table
if (_headers == null)
{
_headers = _dataContext.Mapping.GetMetaType(_rows.ElementType).PersistentDataMembers.Select(m => m.Name).ToArray();
}
// Create Header Row
tw.RenderBeginTag(HtmlTextWriterTag.Thead);
foreach (String header in _headers)
{
if (_headerStyle != null)
_headerStyle.AddAttributesToRender(tw);
tw.RenderBeginTag(HtmlTextWriterTag.Th);
tw.Write(header);
tw.RenderEndTag();
}
tw.RenderEndTag();
// Create Data Rows
tw.RenderBeginTag(HtmlTextWriterTag.Tbody);
foreach (Object row in _rows)
{
tw.RenderBeginTag(HtmlTextWriterTag.Tr);
foreach (string header in _headers)
{
string strValue = row.GetType().GetProperty(header).GetValue(row, null).ToString();
strValue = ReplaceSpecialCharacters(strValue);
if (_itemStyle != null)
_itemStyle.AddAttributesToRender(tw);
tw.RenderBeginTag(HtmlTextWriterTag.Td);
tw.Write(HttpUtility.HtmlEncode(strValue));
tw.RenderEndTag();
}
tw.RenderEndTag();
}
tw.RenderEndTag(); // tbody
tw.RenderEndTag(); // table
WriteFile(_fileName, "application/ms-excel", sw.ToString());
}
private static string ReplaceSpecialCharacters(string value)
{
value = value.Replace("’", "'");
value = value.Replace("“", "\"");
value = value.Replace("”", "\"");
value = value.Replace("–", "-");
value = value.Replace("…", "...");
return value;
}
private static void WriteFile(string fileName, string contentType, string content)
{
HttpContext context = HttpContext.Current;
context.Response.Clear();
context.Response.AddHeader("content-disposition", "attachment;filename=" + fileName);
context.Response.Charset = "";
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.ContentType = contentType;
context.Response.Write(content);
context.Response.End();
}
}
}
ExcelControllerExtensions
using System;
using System.Web.Mvc;
using System.Data.Linq;
using System.Collections;
using System.Web.UI.WebControls;
using System.Linq;
namespace DBFirstMVC.CustomActionResults
{
public static class ExcelControllerExtensions
{
public static ActionResult Excel
(
this Controller controller,
DataContext dataContext,
IQueryable rows,
string fileName
)
{
return new ExcelResult(dataContext, rows, fileName, null, null, null, null);
}
public static ActionResult Excel
(
this Controller controller,
DataContext dataContext,
IQueryable rows,
string fileName,
string[] headers
)
{
return new ExcelResult(dataContext, rows, fileName, headers, null, null, null);
}
public static ActionResult Excel
(
this Controller controller,
DataContext dataContext,
IQueryable rows,
string fileName,
string[] headers,
TableStyle tableStyle,
TableItemStyle headerStyle,
TableItemStyle itemStyle
)
{
return new ExcelResult(dataContext, rows, fileName, headers, tableStyle, headerStyle, itemStyle);
}
}
}
Model1.context.cs
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
namespace DBFirstMVC.Models
{
public partial class PaEntities : DbContext
{
public PaEntities()
: base("name=PaEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public DbSet<iamp_mapping> iamp_mapping { get; set; }
public DbSet<pa_mapping> pa_mapping { get; set; }
}
}
iamp_mapping.cs
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
namespace DBFirstMVC.Models
{
public partial class iamp_mapping
{
public string PA { get; set; }
public string MAJOR_PROGRAM { get; set; }
public string INVESTMENT_AREA { get; set; }
}
}
The reason for the error is right there in the message: cannot convert from 'DBFirstMVC.Models.PaEntities' to 'System.Data.Linq.DataContext. It means that you PaEntities type cannot be converted to System.Data.Linq.DataContext, therefore none of your Excel extension methods' signature matches the arguments you are passing.
What is your PaEntities type? Does it inherit from System.Data.Linq.DataContext?
How can I write HTML in a Word document using C#?
I made a class to help writing a document
using System;
using System.IO;
using Microsoft.Office.Interop.Word;
namespace WordExporter
{
public class WordApplication : IDisposable
{
private Application application;
private Document document;
private string path;
private bool editing;
public WordApplication(string path)
{
this.path = path;
this.editing = File.Exists(path);
application = new Application();
if (editing)
{
document = application.Documents.Open(path, ReadOnly: false, Visible: false);
}
else
{
document = application.Documents.Add(Visible: false);
}
document.Activate();
}
public void WriteHeader(string text)
{
foreach (Section wordSection in document.Sections)
{
var header = wordSection.Headers[WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;
header.Font.ColorIndex = WdColorIndex.wdDarkRed;
header.Font.Size = 20;
header.Text = text;
}
}
public void WriteFooter(string text)
{
foreach (Section wordSection in document.Sections)
{
var footer = wordSection.Footers[WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;
footer.Font.ColorIndex = WdColorIndex.wdDarkRed;
footer.Font.Size = 20;
footer.Text = text;
}
}
public void Save()
{
if (editing)
{
application.Documents.Save(true);
}
else
{
document.SaveAs(path);
}
}
#region IDisposable Members
public void Dispose()
{
((_Document)document).Close(SaveChanges: true);
((_Application)application).Quit(SaveChanges: true);
}
#endregion
}
class Program
{
static void Main(string[] args)
{
using (var doc = new WordApplication(Directory.GetCurrentDirectory() + "\\test.docx"))
{
doc.WriteHeader("<h1>Header text</h1>");
doc.WriteFooter("<h1>Footer text</h1>");
doc.Save();
}
}
}
}
In the WriteHeader I write some text on the document header, but I need to use HTML. How can I say the contents are HTML? I will also need to insert HTML in the document content...
I can just insert the html file on the section I want using:
range.InsertFile("file.html");
For background see my question here.
So the problem now isn't that I can't send a DataSet to classic ASP but that it can't do anything with it. So I found some code to create a recordset xml structure from a DataSet.
I have tweaked it a little from it's original source. The problem is that I can't seem to extract the base stream and use it instead of having to write to a file. What am I missing?
Here is how I am trying to test the class:
[Test]
public void TestWriteToStream()
{
MemoryStream theStream = new MemoryStream();
XmlRecordsetWriter theWriter = new XmlRecordsetWriter(theStream);
theWriter.WriteRecordset( SomeFunctionThatReturnsADataSet() );
theStream = (MemoryStream)theWriter.BaseStream;
string xmlizedString = UTF8ByteArrayToString(theStream.ToArray());
xmlizedString = xmlizedString.Substring(1);
//Assert.AreEqual(m_XMLNotNull, xmlizedString);
Console.WriteLine(xmlizedString);
}
Here is my class:
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text;
using System.Xml;
namespace Core{
public class XmlRecordsetWriter : XmlTextWriter
{
#region Constructors
// Constructor(s)
public XmlRecordsetWriter(string filename) : base(filename, null) { SetupWriter(); }
public XmlRecordsetWriter(Stream s) : base(s, null) { SetupWriter(); }
public XmlRecordsetWriter(TextWriter tw) : base(tw) { SetupWriter(); }
protected void SetupWriter()
{
base.Formatting = Formatting.Indented;
base.Indentation = 3;
}
#endregion
#region Methods
// WriteRecordset
public void WriteRecordset(DataSet ds) { WriteRecordset(ds.Tables[0]); }
public void WriteRecordset(DataSet ds, string tableName) { WriteRecordset(ds.Tables[tableName]); }
public void WriteRecordset(DataView dv) { WriteRecordset(dv.Table); }
public void WriteRecordset(DataTable dt)
{
WriteStartDocument();
WriteSchema(dt);
WriteContent(dt);
WriteEndDocument();
}
// WriteStartDocument
public void WriteStartDocument()
{
base.WriteStartDocument();
base.WriteComment("Created by XmlRecordsetWriter");
base.WriteStartElement("xml");
base.WriteAttributeString("xmlns", "s", null, "uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882");
base.WriteAttributeString("xmlns", "dt", null, "uuid:C2F41010-65B3-11d1-A29F-00AA00C14882");
base.WriteAttributeString("xmlns", "rs", null, "urn:schemas-microsoft-com:rowset");
base.WriteAttributeString("xmlns", "z", null, "#RowsetSchema");
}
// WriteSchema
public void WriteSchema(DataSet ds) { WriteSchema(ds.Tables[0]); }
public void WriteSchema(DataSet ds, string tableName) { WriteSchema(ds.Tables[tableName]); }
public void WriteSchema(DataView dv){ WriteSchema(dv.Table); }
public void WriteSchema(DataTable dt)
{
// Open the schema tag (XDR)
base.WriteStartElement("s", "Schema", null);
base.WriteAttributeString("id", "RowsetSchema");
base.WriteStartElement("s", "ElementType", null);
base.WriteAttributeString("name", "row");
base.WriteAttributeString("content", "eltOnly");
// Write the column info
int index=0;
foreach(DataColumn dc in dt.Columns)
{
index ++;
base.WriteStartElement("s", "AttributeType", null);
base.WriteAttributeString("name", dc.ColumnName);
base.WriteAttributeString("rs", "number", null, index.ToString());
base.WriteEndElement();
}
// Close the schema tag
base.WriteStartElement("s", "extends", null);
base.WriteAttributeString("type", "rs:rowbase");
base.WriteEndElement();
base.WriteEndElement();
base.WriteEndElement();
}
// WriteContent
public void WriteContent(DataSet ds) { WriteContent(ds.Tables[0]); }
public void WriteContent(DataSet ds, string tableName) { WriteContent(ds.Tables[tableName]); }
public void WriteContent(DataView dv) { WriteContent(dv.Table); }
public void WriteContent(DataTable dt)
{
// Write data
base.WriteStartElement("rs", "data", null);
foreach(DataRow row in dt.Rows)
{
base.WriteStartElement("z", "row", null);
foreach(DataColumn dc in dt.Columns)
base.WriteAttributeString(dc.ColumnName, row[dc.ColumnName].ToString());
base.WriteEndElement();
}
base.WriteEndElement();
}
// WriteEndDocument
public void WriteEndDocument()
{
base.WriteEndDocument();
base.Flush();
base.Close();
}
#endregion
}
}
I think you want to work with Data-based objects and XML based data.
If it's true, I suggest using ADODB Classes (It is in COM References: Microsoft ActiveX Data Objects 6.0 Library -Or in other versions like 2.8-).
You can convert your DataTable to a ADODB.Recordset by this code: Simplest code to convert an ADO.NET DataTable to an ADODB.Recordset.
So you have a ConvertToRecordset() method to use in next code.
Now you need only save() method to have your XML file:
using ADODB;
using System;
using System.Data;
using System.IO;
namespace ConsoleApplicationTests
{
class Program
{
static void Main(string[] args)
{
Recordset rs = new Recordset();
DataTable dt = sampleDataTable(); //-i. -> SomeFunctionThatReturnsADataTable()
//-i. Convert DataTable to Recordset
rs = ConvertToRecordset(dt);
//-i. Sample Output File
String filename = #"C:\yourXMLfile.xml";
FileStream fstream = new FileStream(filename, FileMode.Create);
rs.Save(fstream, PersistFormatEnum.adPersistXML);
}
}
}
The power of ADODB.Recordset is here that you can open that saved XML file very easy:
rs.Open(fstream);
I hope it works!, Actually I wrote this answer to complete it later and if I'm in a right direction.
First, the line:
theStream = (MemoryStream)theWriter.BaseStream;
is redundant as the MemoryStream should already be the base stream for the writer.
What it sounds like you want is just:
theWriter.Close();
theStream.Position = 0; // So you can start reading from the begining
string xml = null;
using (StringReader read = new StringReader(theStream))
{
xml = read.ReadToEnd();
}
Then xml will be your xml string that you can load into an XPathDocument or XmlDocument and play with however you want.