Append DataVizualisation Chart Control to text file - c#

I'm developing a system that takes data input from textboxes, and on a button click, saves these values to the respective listbox ready to be written to a text file once the process is complete.
The next stage has been using this data to create graphs, which has gone successfully but I'm now looking for a way to add these onto the end of my text file so it's all included in one place.
I originally tried it like this (included in the total 'saveToFile' function):
consoleFile.WriteLine(chartBP.Text); //chart title
chartBP.SaveImage((fileName), System.Drawing.Imaging.ImageFormat.Jpeg);
consoleFile.WriteLine("\n\n");
This appeared to work ok but threw a run-time error stating that the file could not be accessed because it was being used by another process.
I don't think I'm far off where I need to be, but I don't have enough experience with charts to know what to try next.
Does anyone have any idea how to make this work, or another method that wouldn't produce the error?
Any help is greatly appreciated!

If your problem is just to get rid of the exception, then you could do this:
consoleFile.WriteLine(chartBP.Text);
consoleFile.Close();
FileStream imgFile = File.Open(filename, FileMode.Append);
chartBP.SaveImage(imgFile, ChartImageFormat.Jpeg);
imgFile.Close();
consoleFile = new StreamWriter(filename, true);
consoleFile.WriteLine("\n\n");
consoleFile.Close();
But remember, you're not going to see any images in your text file, just a messy stream of characters corresponding to the binary image, displayed as text.

Related

How to read file in C# from POST data from web

Basically, I'm building a website that allows user to upload file.
From the front end (JavaScript), the user will browse a file, I can get the site to send POST data (the parameter "UploadInput" and it's value, which the value is the file)
In the backend (C#), I want to make a copy of the file and save it in a specific path.
Below is the way I did it.
var files = Request.Files;
file[0].SaveAs("\temp\\" + file[0].FileName);
The problem I ran into is that I got the error message saying index out of range. I tried Response.Write(files.Count) and it gives me 0 instead of 1.
I'm wondering where I did wrong and how to fix it, or if there's a better way of doing it.
Thanks!
Edit:
I am using HttpFox to debug. From HttpFox, I can see that under POST data, parameter is "UploadInput" and the value is "test.txt"
Edit 2:
So I tried the way Marc provides, and I have a different problem.
I am able to create a new file, however, the content is not copied over. I tried opening the new created file in notepad and all it says is "UploadInput = test.txt"
If they simply posted the file as the body content, then there will be zero "files" involved here, so file[0] will fail. Instead, you need to look at the input-stream, and simply read from that stream. For example:
using(var file = File.Create(somePath)) {
Request.InputStream.CopyTo(file);
}

Copy Excel RangeSelection to array in Windows Application

Thanks for any help in advance :)
Context
I am using SpreadsheetGear within my Windows Application and there are certain cases where a user will want to copy data from an open Excel application and paste the two dimensional grid into the SpreadsheetGear object in my application.
Motivation
I'm attempting to acquire information from the data in the clipboard in preparation for the paste to happen. The numbers of rows and columns of the data coming in needs to be determined before the paste happens so that the SpreadsheetGear control and other controls on the page are "ready" for the data.
Problem 1
How do I acquire such data from the Clipboard? I'm using
System.Windows.Forms.Clipboard.GetData(...)
but I'm not sure whether I should indicate the DataFormat to be CommaSeparatedValue (CSV) or Text. Will one way or the other work best? Is there another DataFormat that I am overlooking that could help me out?
Problem 2
I used this statement in the Immediate Window of Visual Studio 2012:
System.Diagnostics.Debug.WriteLine(Clipboard.GetText())
Interestingly, this returned a portion of the data I selected and copied in Excel. Is there a limit to the amount of data that the clipboard can handle from Excel? Or is there a way for my Windows App to help allocate more space on the clipboard, knowing the user is about the select data from Excel and copy that data to the clipboard?
Please let me know if I can provide more clarification. I'm a little lost and not sure about the scope of this issue. Thanks!
Here is what ended up working for me:
try
{
var data = Clipboard.GetDataObject();
var stream = (System.IO.Stream)data.GetData(DataFormats.CommaSeparatedValue);
var enc = new System.Text.UTF8Encoding();
var reader = new System.IO.StreamReader(stream, enc);
string data_csv = reader.ReadToEnd();
string[] data_csv_array = data_csv.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
...
}
catch (Exception e)
{
ErrorHandling.ShowError("There is no data on the Clipboard to paste.");=
}
The "..." indicates that I do something pretty particular with the data once I have it in array form. What I wanted to do was display the portion of my solution that would help people in general with a similar need.

How may I get the image of DataVisualization.Charting.Chart to iTextSharp.text.Image without writing to a file?

I'm writing a piece of software for visualization of measurement data. For this I use System.Windows.Forms.DataVisualization.Charting.Chart and I do know that I can get the shown image by chartObj.SaveImage to store it to a file.
My software shall have a PDF export in which the picture should be included. For this, I'm using iTextSharp. Again, I do know how to put a picture which I have stored in a file into the PDF by iTextSharp.text.Image.GetInstance.
So by now I am able to take the picture of the chart, put it to a file (e.g. a .jpg file) and load this file again to put it in my PDF. Now I'm looking for a nice solution to get the picture into the PDF without storing it into a file, maybe through a Stream or something like that. I've tried quite some time, but until now I didn't succeed. I've thought of something like
Stream imageStream = image of chartObj;
iTextSharp.text.Image picture = iTextSharp.text.Image.GetInstance(imageStream);
As far as I understand, I fail in putting the picture from the chartObj into a Stream instead of a file. If I had this, I guess I could load the Stream via iTextSharp.text.Image.GetInstance.
Has anyone some help you could offer? Guess it's not that difficult, but I'm new to C# and also to iText, so I'm just a bit stucked here.
Thanks in advance for every thought you have about this!
Anna
SaveImage to a MemoryStream:
using (var chartimage = new MemoryStream())
{
chart.SaveImage(chartimage, ChartImageFormat.Png);
return chartimage.GetBuffer();
}
From:
Microsoft Chart Controls to PDF with iTextSharp and ASP.NET MVC

how to know what part of my application use the file

In my application I scan images and creat a treeview and when I click on the name of file I show the image in imageViewer,
but when I use delete directory after that I clear the treeview and the imageviewer
treevImage.Nodes.Clear();
imageViewer.Image.Dispose();
imageViewer.Image = null;
Directory.Delete(localPath, true);
I got an exception that one image was used by another thread, the problem is that it is random, the first one or any other image!
The process cannot access the file 'image9.tif' because it is being used by another process.
Is there a way to know which part of my application uses that image?
Edit :
When I add
imageViewer.Dispose();
l'app delete the files without exception but when I scan again I got exception when show a new image in imageViewer
Object reference not set to an instance of an object.
Edit 2:
Exception do to dispose() was corrected by MikeNakis but now After I delete the directory I make a new scan and to show the new images in the imageViewer, after dispose() and new ; I can't see the new images for the new scan
Once you have disposed the imageViewer with imageViewer.Dispose(); you need to then re-create it with imageViewer = new ImageViewer();.
I occasionally have to wait a few ms after closing and disposing a file before it is available for reading on the same thread - just as you describe above. I solved this by writing a method which wait until I had exclusive access to the file.
File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None)
Remember to put a thread.sleep in that loop. If this locks up your program, you're forgetting to dispose something.
(I never investigated why this was required since the workaround was successful and has been in use for almost 10 year now. Could be a bug in my code, but since I was writing to the file before closing/disposing it I suspect that our anti-virus software placed a brief lock on the file)
Another solution is to prevent the image object locking the file at all. You can read the image file into a memory stream, and instantiate the image from it. Just ensure you do this right so that you don't end up copying the image around in memory more than neccessary.

PDF generated with itext becomes 'corrupted' when using SetSimpleColumn()

First I would like to point out that stackowerflow helped me with many problems in the past, so thank you all. But now I have come to problem that I haven't fount a solution for yet and it's driving me crazy. I'm not native english speaker, so sorry for any language mistakes.
So here it is:
I'm generating pdf with itextsharp library(great library by the way). I'm starting with some kind of pdf form/template, to which i'm adding 'fill-out' data. I'm using PdfReader to read template pdf and by caling PdfStamper method GetOverContent(pageNum) for individual pages I get PdfContentByte. With that PdfContentByte I'm adding my text/data (BeginText and EndText is used on every page). Most of text I add with method ShowTextAligned. That all ok, generated pdf contains my text. The problem begins where i have to add 'columned' text. I do that with following code:
ColumnText ct = new ColumnText(cb);//cb is PdfContentByte
Phrase p = new Phrase(txt, FontFactory.GetFont(DEFAULT_FONT, BaseFont.CP1250, true, font_size));
ct.SetSimpleColumn(p, x, y, x+width, y+height, 10, alignment);
ct.Go();
setDefaultFont();//sets font to PdfContentByte again with setFontAndSize and SetColorFill
Columned text is added with this code OK, but the text(on that same page/same PdfContentByte) added AFTER this with ShowTextAligned is not visible in Acrobat Reader.
Here is the 'fun' part - that text in same pdf file opened with foxit reader is fine/visible/ok.
So text added with ShowTextAligned after adding ColumnText is not visible in acrobat reader but visible in foxit reader just fine. This problem exists inside one page, new page resets this problem (PdfContentByte for next page is new).
My workaround for that was to add all ColumnText AFTER all calls of ShowTextAligned. That worked till today, when customer printed out generated pdf with acrobat reader, which after printing the document, displayed message that pdf contains error and that author of pdf should be contacted. Version of Adobe Reader is 10.1.1. Problem is not in customer computer, same thing hapens on my computer.
After researching the web I installed Adobe Acrodat Pro Trial which contains tool Preflight, which is purposed for analyzing pdfs (as far I understand). This tool outputs warning "Invalid content state stream for operator". And here I'm stucked. I belive the problem exists inside added ColumnText, because document generated without them causes no problem displaying/printing and Preflight states "No problem found".
It is possible that i'm missing some fact and that the problem is in my code...
Please help me, because i'm runnig out of ideas.
I hope this post will help someday someone else with the same problem.
I cannot attach sample pdf because it contains sensitive data, but if there is no other way, i'll recreate the scenario/code.
So to answer my question/problem:
When writing to pdf using PdfContentByte and using method ShowTextAligned you have to call BeginText before writing and after you are finished you have to call EndText. So i did. BUT if you want to add some other element(like ColumnText, Image and probably anything else) you can't do that before you call EndText. If you do, generated pdf will be 'problematical'/corrupted.
So in pseudocode following is wrong:
BeginText();
ShowtextAligned();
AddImage();
ShowtextAligned();
EndText();
Correct usage is:
BeginText();
ShowtextAligned();
EndText();
AddImage();
BeginText();
ShowtextAligned();
EndText();
I hope this will help someone someday somewhere.

Categories