I'm using the FileHelpers library for a C# .net project. All is working ok except I need to have the generated CSV savable via a button click.
So the user clicks a button and they get a prompt to save the file. I know Filehelpers has a WriteStream option but their own documentation shows only an example of WriteFile. I don't know if WriteStream is what's needed but I think it is.
Anyone know if it's possible to have the CSV file saved directly to the client rather than to the server hard drive?
Thanks.
UPDATE WITH MORE DETAIL:
I'll try to give more detail to help clarify what it is I'm trying to achieve. I don't want to save any file on the server. I am using FileHelpers to generate a record and I want to try and use their WriteStream method to write that record as a CSV directly to their browser; but the example they provide doesn't actually use that method at all, strangely.
Here's the link to their method:
http://www.filehelpers.com/FileHelpers.FileHelperEngine.WriteStream_overload_2.html
And here's the method in question.
public void WriteStream(
TextWriter writer,
IEnumerable records,
int maxRecords
);
I can easily save the file to the server but don't want to as I've no need for it and want to get the client to save it directly to their own machine.
It may be that I have to go through the normal route to achieve this but I saw the WriteStream method and thought maybe FileHelpers facilitated a nice clean way of achieving the same result.
Hope this is clearer.
You should be able to do something like the following:
Response.ContentType = #"application/x-msdownload";
Response.AppendHeader("content-disposition", "attachment; filename=" + FILE_NAME);
Response.Write(csv.ToString());
Response.Flush();
Response.End();
There are plenty of more elaborate suggestions on StackOverflow such as this one. It depends what you are trying to achieve.
EDIT
I think the steps you are missing are:
MemoryStream stream = new MemoryStream();
StreamWriter streamWriter = new StreamWriter(stream);
engine.WriteStream(streamWriter, records);
stream.Position = 0;
and then you can use
StreamReader reader = new StreamReader(stream);
Response.Write(reader.ReadToEnd);
instead of Response.Write(csv.ToString()) in my first example above.
Don't forget to flush StreamWriter. See example
public MemoryStream CreateCsvFileAsMemoryStream(List<TestItem> testItems) {
var engine = new FileHelperEngine<TestItemCsvMapping>();
var items = testItems.Select(ti => (TestItemCsvMapping)ti).ToList();
engine.HeaderText = engine.GetFileHeader();
var ms = new MemoryStream();
var sw = new StreamWriter(ms);
engine.WriteStream(sw, items);
sw.Flush();
//var reader = new StreamReader(ms);
//ms.Position = 0;
//Console.Write(reader.ReadToEnd());
ms.Position = 0;
return ms;
}
Related
in my Hololens app i want to write data into a file which i can then view over the Device Portal. The Data contains just the time from one airtap on a special object to another airtap.
The problem ist that there will be no file created in the Device Portal under /LocalAppData/YourApp/LocalState
Thanks in advance
Jonathan
public void StopTime()
{
TimeSpan ts = time.Elapsed;
time.Stop();
path = Path.Combine(Application.persistentDataPath, "Messdaten.txt");
using (TextWriter writer = File.CreateText(path))
{
writer.Write(ts);
}
}
I usually use a FileStream and a StreamWriter and make sure the FileMode.Create is set.
See also How to write text to a file for more approaches
using (var file = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Write))
{
using (var writer = new StreamWriter(file, Encoding.UTF8))
{
writer.Write(content);
}
}
With that I never had any trouble on the HoloLens so far.
You also might want to use something like ts.ToString() in order to format the value to your needs.
Alternatively you could also try Unity's Windows.File (only available for UWP) but than you need to have byte[] as input. E.g. from here
long c = ts.Ticks;
byte[] d = BitConverter.GetBytes(c);
File.WriteAllBytes(path, d);
The simplest thing to do is to use File.WriteAllText method https://learn.microsoft.com/en-us/dotnet/api/system.io.file.writealltext?view=netframework-4.7.2
Obviously there are many ways that could work but it is good to stick to the simplest solution.
Hi I am trying to convert DOCX to PDF conversion in C# using only telerik controls not any other third party assemblies or introp.
I found similar questions in stack overflow but didn't get the proper answer means unable to proceed with those approaches.
Thanks in advance.
Please Try this.You may take some help from this.
RadDocument document = null;
IDocumentFormatProvider providerDocx = (IDocumentFormatProvider) new DocxFormatProvider();
using (FileStream stream = File.Open(#"C:\Test.docx", FileMode.Open))
{
document = providerDocx.Import(stream);
var providerPdf = new PdfFormatProvider();
Stream outStream = new MemoryStream();
providerPdf.Export(document, outStream);
//Test the conversion:
var fileStream = File.Create("PdfTest.pdf");
outStream.Seek(0, SeekOrigin.Begin);
outStream.CopyTo(fileStream);
fileStream.Close();
}
Edit: The original question was made out of a misunderstanding, and has been updated.
Coming from other languages it seems odd that C# does not seem to have a simple way to dump things like objects and components straight to file.
Lets take java as an example, where I can dump any object to file and load with no apparent restrictions:
//Save object to file:
FileOutputStream saveFile = new FileOutputStream(---filePath---);
ObjectOutputStream save = new ObjectOutputStream(saveFile);
save.writeObject(---YorObjectHere---);
//Load object from file
FileInputStream saveFile = new FileInputStream(---filePath---);
ObjectInputStream save = new ObjectInputStream(saveFile);
---ObjectType--- loadedObject = (---ObjectType---) save.readObject();
Can this sort of thing be easily achieved in C#?
I have tried the standard method of serialization:
//Save object to file:
IFormatter formatterSave = new BinaryFormatter();
Stream streamSave = new FileStream(---filePath---, FileMode.Create, FileAccess.Write, FileShare.None);
formatterSave.Serialize(streamSave, ---ObjectToSave---);
//Load object from file
IFormatter formatterLoad = new BinaryFormatter();
Stream streamLoad = new FileStream(---filePath---, FileMode.Open, FileAccess.Read, FileShare.Read);
---ObjectType--- ---LoadedObjectName--- = (---ObjectType---)formatterLoad.Deserialize(streamLoad);
While this method is quite simple to do, it does not always work with existing or locked code because the [serializable] tag cannot always be added.
So what is the best alternate for serialization?
Thanks to comments I tried the XML method, but it did not work either because it cannot serialize an ArrayList as shown on MSDN
//Save object to file:
var serializerSave = new XmlSerializer(typeof(objectType));
writer = new StreamWriter(filePath, append);
serializerSave.Serialize(writer, objectToWrite);
//Load object from file
var serializerLoad = new XmlSerializer(typeof(objectType));
reader = new StreamReader(filePath);
return (T)serializerLoad.Deserialize(reader);
It looks like JSON is the only way to do it easily, or is there another alternate way to serialize with normal C# libraries without needing massive amounts of code?
Thanks to those who commented and pointed me in the right direction.
Although its not covered in the basic libraries, using JSON looks like the best alternate in this situation, I plan to use Json.NET, it can be found here: http://www.nuget.org/packages/Newtonsoft.Json
Another good option is Google Gson: https://code.google.com/p/google-gson/
I'm currently trying to use iTextSharp to do some PDF field mapping, but the challenging part right now is just saving the modified file in a varbinary[max] column. Then I later need to read that blob and convert it into a pdf which I save to a file.
I've been all over looking at example code but I can't find exactly what I'm looking for, and can't seem to piece together the [read from file to iTextSharp object] -> [do my stuff] -> [convert to varbinary(max)] pipeline, nor the conversion of that blob back into a savable file.
If anyone has code snippet examples that would be extremely helpful. Thanks!
The need to deal with a pdf in multiple passes was not immediately clear when I first started working them, so maybe this is some help to you.
In the method below, we create a pdf, render it to a byte[], load it for post processing, render the pdf again and return the result.
The rest of your question deals with getting a byte[] into and out of a varbinary[max], saving a byte[] to file and reading it back out, which you can google easily enough.
public byte[] PdfGeneratorAndPostProcessor()
{
byte[] newPdf;
using (var pdf = new MemoryStream())
using (var doc = new Document(iTextSharp.text.PageSize.A4))
using (PdfWriter.GetInstance(doc, pdf))
{
doc.Open();
// do stuff to the newly created doc...
doc.Close();
newPdf = pdf.GetBuffer();
}
byte[] postProcessedPdf;
var reader = new PdfReader(newPdf);
using (var pdf = new MemoryStream())
using (var stamper = new PdfStamper(reader, pdf))
{
var pageCount = reader.NumberOfPages;
for (var i = 1; i <= pageCount; i++)
{
// do something on each page of the existing pdf
}
stamper.Close();
postProcessedPdf = pdf.GetBuffer();
}
reader.Close();
return postProcessedPdf;
}
Does any one know how to use the package.Saveas function?
package.SaveAs(tempFolderPathAlt + saveas + ".xlsx");
At the moment this is underlined in red with the following error:
The best overloaded method match for
'OfficeOpenXml.ExcelPackage.SaveAs(System.IO.Stream)' has some invalid
arguments
At the moment i'm saving the file in the following way.
FileStream aFile = new FileStream(tempFolderPathAlt + saveas + ".xls", FileMode.Create);
byte[] byData = package.GetAsByteArray();
aFile.Seek(0, SeekOrigin.Begin);
aFile.Write(byData, 0, byData.Length);
aFile.Close();
But this way the package remains open and i cant work with files it has used.
The save as will close the package properly, but its not accepting my file path.
Edit
I tried this:
using (FileStream aFile = new FileStream(tempFolderPathAlt + saveas + ".xlsx", FileMode.Create))
{
byte[] byData = package.GetAsByteArray();
aFile.Seek(0, SeekOrigin.Begin);
package.SaveAs(aFile);
//aFile.Write(byData, 0, byData.Length);
aFile.Close();
}
But Get the following error?
Package object was closed and disposed, so cannot carry out operations on this object or any stream opened on a part of this package.
The package will be closed & disposed after you call any of functions GetAsByteArray, Save, SaveAs. That is the reason why you got message
Package object was closed and disposed, so cannot carry out operations on this object or any stream opened on a part of this package.
The solution is that after the saving you call Load function to continue processing on excel file. Or if you just want to get both ByteArray & FileOutput, I'm sure with you they both are same.
You can read data after have saved file to the disk:
string path = #"C:\test1.xlsx";
Stream stream = File.Create(path);
package.SaveAs(stream);
stream.Close();
byte[] data = File.ReadAllBytes(path);
Or you can save data to disk after get the ByteArray:
byte[] data = package.GetAsByteArray();
string path = #"C:\test1.xlsx";
File.WriteAllBytes(path, data);
I came looking for the answer to this but the existing answers were not clear to me.
Here is what I did using EPPlus and System.Windows.Forms:
ExcelPackage xlPackage = new ExcelPackage(xlsTmpFileName)
// Populate the Excel spreadsheet here.
SaveFileDialog sfd = new SaveFileDialog();
using (FileStream fs = new FileStream(sfd.FileName, FileMode.Create))
{
xlPackage.SaveAs(fs);
}
I dont know from which version onwards but EPPlus's SaveAs method accepts a FileInfo. So you could do something like this:
using (var app = new ExcelPackage(new FileInfo(inputPath)))
{
//process
app.SaveAs(new FileInfo(outputPath));
}
Unlike the Save method SaveAs method overwrites file as well in case file name already exists.
SaveAs would be accepting your aFile Stream.
You can find out such things yourself by looking at the function signature: SaveAs(System.IO.Stream). It takes a Stream. Passing a string cannot possibly compile so you have to somehow make up a useful Stream (which you did).
Get rid of the surplus package.GetAsByteArray call and you should solve it.
I just ran:
using (FileStream aFile = new FileStream(#"C:\Temp\asdf.xlsx", FileMode.Create))
{
aFile.Seek(0, SeekOrigin.Begin);
package.SaveAs(aFile);
aFile.Close();
}
// See here - I can still work with the spread sheet.
var worksheet = package.Workbook.Worksheets.Single();