Loading RTF file with images to FlowDocument in console application - c#

I am creating simple console application where I need to load RTF file to FlowDocument for further work.
I am using this code for loading file to FlowDocument:
// Create OpenFileDialog
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
// Set filter for file extension and default file extension
dlg.DefaultExt = ".rtf";
dlg.Filter = "RichText Files (*.rtf)|*.rtf";
// Display OpenFileDialog by calling ShowDialog method
Nullable<bool> result = dlg.ShowDialog();
if (result == true)
{
// Open document
string filename = dlg.FileName;
FlowDocument flowDocument = new FlowDocument();
TextRange textRange = new TextRange(flowDocument.ContentStart, flowDocument.ContentEnd);
using (FileStream fileStream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
{
textRange.Load(fileStream, DataFormats.Rtf);
}
}
If I do this in WPF application and show the document in flowDocumentPageViewer, everything is OK. But if I try to load file in console application, I get exception: Unrecognized structure in data format Rich Text Box, parameter name stream.
And for some reason, this exception appears only, if there is image in document.
Any ideas what's wrong or better how to solve it?

Problem was in using System.Windows namesapce for DataFormats. With System.Windows.Forms its functional.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Windows.Documents;
namespace RtfTest
{
class Program
{
[STAThread]
static void Main(string[] args)
{
DoRead();
}
private static void DoRead()
{
// Create OpenFileDialog
OpenFileDialog dlg = new OpenFileDialog();
// Set filter for file extension and default file extension
dlg.DefaultExt = ".rtf";
dlg.Filter = "RichText Files (*.rtf)|*.rtf";
// Display OpenFileDialog by calling ShowDialog method
var result = dlg.ShowDialog();
try
{
if (result == DialogResult.OK)
{
// Open document
string filename = dlg.FileName;
FlowDocument flowDocument = new FlowDocument();
TextRange textRange = new TextRange(flowDocument.ContentStart, flowDocument.ContentEnd);
using (FileStream fileStream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
{
textRange.Load(fileStream, DataFormats.Rtf);
}
}
}
catch (Exception)
{
throw;
}
}
}
}

Related

Converting Multiple Images to PDF with iTextSharp

I am trying to convert a series of images taken from OpenFileDialog() to one PDF using iTextSharp in C#. Here is what I'm running. When I select files I get the error: "System.NotSupportedException: 'Stream does not support reading.'"
on the line :
var image = iTextSharp.text.Image.GetInstance(imageStream);
I am wondering what this error means, or what I could fix to resolve the issue. Thanks.
namespace WindowsFormsApp2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private OpenFileDialog ofd = new OpenFileDialog { Multiselect = true, Filter = "Image files | * .jpg;*.jpeg;*.png;" };
// Open file button
private void button1_Click(object sender, EventArgs e)
{
// Run code only if a file is selected
if (ofd.ShowDialog() == DialogResult.OK)
{
Document doc = new Document();
using (var stream = new FileStream("test.pdf", FileMode.Create, FileAccess.Write, FileShare.None))
{
foreach (String file in ofd.SafeFileNames)
{
using (var imageStream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
PdfWriter.GetInstance(doc, stream);
doc.Open();
var image = iTextSharp.text.Image.GetInstance(imageStream);
doc.Add(image);
doc.Close();
}
}
}
}
}
}
}
Here is the main code:
namespace WindowsFormsApp2
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
Try the code below, I've moved the opening and closing of doc outside of the foreach loop. Calling doc.Close() closes the parent file stream, so it's important to only call doc.Close() once all the images have been added.
using (var stream = File.Create("test.pdf"))
using (var doc = new Document())
using (var pdfWriter = PdfWriter.GetInstance(doc, stream))
{
doc.Open();
foreach (var file in ofd.SafeFileNames)
{
using (var imageStream = File.OpenRead(file))
{
var image = Image.GetInstance(imageStream);
doc.Add(image);
}
}
doc.Close();
}

Create a .txt file if doesn't exist with user inputted data

Is there any way to create a text file using a name that comes from data entered in a form?
string path = #"E:\AppServ\**Example**.txt";
if (!File.Exists(path))
{
File.Create(path);
}
**Example** being the part taken from user inputted data.
Similar to this Console.Writeline("{0}", userData);
Here is an example of how to store files to the logged in users My Documents folder on windows.
You can modify the AppendUserFile function to support other file modes. This version will open the file for Appending if it exists, or create it if it doesn't exist.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
AppendUserFile("example.txt", tw =>
{
tw.WriteLine("I am some new text!");
});
Console.ReadKey(true);
}
private static bool AppendUserFile(string fileName, Action<TextWriter> writer)
{
string path = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
string filePath = Path.Combine(path, fileName);
FileStream fs = null;
if (File.Exists(filePath))
fs = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.Read);
else
fs = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Read);
using (fs)
{
try
{
TextWriter tw = (TextWriter)new StreamWriter(fs);
writer(tw);
tw.Flush();
return true;
}
catch
{
return false;
}
}
}
}
}

Parse a file path with FileChooserDialog GtkSharp

I am using a StreamReader in WeatherController.cs to read data form a CSV file. And in my MainWindow i am using a FileChooseDialog to find the file to read from. Like so:
protected void OnButton2Clicked (object sender, EventArgs e)
{
//Open file dialog and choose a file.
Gtk.FileChooserDialog fc=
new Gtk.FileChooserDialog("Choose the file to open",
this,
Gtk.FileChooserAction.Open,
"Cancel",Gtk.ResponseType.Cancel,
"Open",Gtk.ResponseType.Accept);
fc.Filter = new FileFilter ();
fc.Filter.AddPattern ("*.csv");
if (fc.Run() == (int)Gtk.ResponseType.Accept)
{
b_Next.Sensitive = true;
System.IO.FileStream file = System.IO.File.OpenRead(fc.Filename);
file.Close();
}
//Destroy() to close the File Dialog
fc.Destroy();
}
How do i get the file path from this file to be used in my WeatherController.cs StreamReader?
My StreamReader:
using (StreamReader sr = new StreamReader (file))
string folder = Path.GetDirectoryName( file );

Asp.net FileStream Create throws error if file doesn't exist

I have a file path that might exist or might not exist.
I want to create / override the file, and i have this code:
string filePath = GetFilePath();
using (FileStream file = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None))
{
xDoc.Save(file);
}
When i call using (FileStream file ...) and the file doesn't exist, it throws an Could not find a part of the path... error.
I am doing something wrong? shouldn't it create the file if doesn't exist?
FileStream can't create intermediate directories that don't exist. This question should help you.
FileMode.OpenOrCreate creates a file if it doesn't exist. If you also need to create the directory:
bool dirExists = System.IO.Directory.Exists(dir);
if(!dirExists)
System.IO.Directory.CreateDirectory(dir);
using(var fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
{
}
OpenOrCreate
Specifies that the operating system should open a file if it exists;
otherwise, a new file should be created.
try this:
void OpenOrCreateFile()
{
try
{
string filePath = GetFilePath();
EnsureFolder(filePath); //if directory not exist create it
using(var fs = new FileStream(filePath, FileMode.OpenOrCreate))
{
//your code
}
}
catch(Exception ex)
{
//handle exception
}
}
void EnsureFolder(string path)
{
string directoryName = Path.GetDirectoryName(path);
if ((directoryName.Length > 0) && (!Directory.Exists(directoryName))
{
Directory.CreateDirectory(directoryName);
}
}
You can use StreamWriter has a boolean parameter append to overwrite the file it contents exits
http://msdn.microsoft.com/en-IN/library/36b035cb.aspx
public StreamWriter(
string path,
bool append
)
You can use the below given code
using System;
using System.IO;
using System.Text;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
string fileName = "test.txt";
string textToAdd = "Example text in file";
using (StreamWriter writer = new StreamWriter(fileName, false))
{
writer.Write(textToAdd);
}
}
}
}

How do import Xml file into Word Content Controls

I was able to create a Word Document with content controls mapped to an Xml schema and using the code from this blog: http://seroter.wordpress.com/2009/12/23/populating-word-2007-templates-through-open-xml/ I am able to insert data into the word document.
The question I have is, is it possible to replace the the code below so that I can use an Xml file instead of having to write this for each finding:
//create XML string matching schema custom XML path
string newXml = "<root>" +
"<FINDING>Adobe Flash Player contains multiple...</FINDING>" +
"<STATUS>Open</STATUS>" +
"<THREATLEVEL>High</THREATLEVEL>" +
"<RECOMMENDATION>Update Flash Player to version...</RECOMMENDATION>" +
"<DEVICEAFFECTED>UserPC</DEVICEAFFECTED>" +
"<SCANNER>XXXXXX</SCANNER>" +
"</root>";
I have tried replacing this with:
string newXml = #"C:\Users\Christopher\Desktop\BookData\TestReport.xml";
and created a nested using statement with StreamReader and the existing StreamWriter but the word document would not populate and there would not be any errors.
--I just tried to replace that code with this:
//create XML string matching schema custom XML path
string newXml = #"C:\Users\Christopher\Desktop\BookData\TestReport.xml";
using (StreamReader sr = new StreamReader (newXml))
{
newXml = sr.ReadToEnd();
}
and I no longer get the error when I open the document, but the content controls are not populating?
Thank you.
Turns out the problem I was running into was that my code and examples were not actually deleting the previous CustomXMLParts located in the "CustomXML" folder. I the code working in two ways, the first is a Windows Form App with one button (btnGenerate) which allows you to select both the template.docx and customXML.xml files. The second is the a Console Program.
Cheers
Windows Form Application:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DocumentFormat.OpenXml.Packaging;
using System.IO;
using System.Threading;
namespace TestReportCreator_Beta
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[STAThread]
private void btnGenerate_Click(object sender, EventArgs e)
{
string outFile = #"C:\Users\Christopher\Desktop\BookData\TestReportBetaEND.docx";
OpenFileDialog OFD = new OpenFileDialog();
OFD.Multiselect = false;
OFD.Title = "Open Word Document";
OFD.Filter = "Word Document|*.docx;*.domx";
OFD.ShowDialog();
string docPath = OFD.FileName;
OFD.Title = "Opne Xml Document";
OFD.Filter = "Xml Document|*.xml";
OFD.ShowDialog();
string xmlPath = OFD.FileName;
// convert template to document
File.Copy(docPath, outFile);
using (WordprocessingDocument doc = WordprocessingDocument.Open(outFile, true))
{
MainDocumentPart mdp = doc.MainDocumentPart;
if (mdp.CustomXmlParts != null)
{
mdp.DeleteParts<CustomXmlPart>(mdp.CustomXmlParts);
}
CustomXmlPart cxp = mdp.AddCustomXmlPart(CustomXmlPartType.CustomXml);
FileStream fs = new FileStream(xmlPath, FileMode.Open);
cxp.FeedData(fs);
mdp.Document.Save();
}
}
}
}
Here is the Console Program Version
using System; using System.Collections.Generic;
using System.Linq; using System.Text;
using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing; using System.IO;
namespace BookData
{
class Program
{
static void Main(string[] args)
{
string template = #"C:\Users\Christopher\Desktop\BookData\TestReportBeta.docx";
string outFile = #"C:\Users\Christopher\Desktop\BookData\TestReportBetaEND.docx";
string xmlPath = #"C:\Users\Christopher\Desktop\BookData\TestReport.xml";
// convert template to document
File.Copy(template, outFile);
using (WordprocessingDocument doc = WordprocessingDocument.Open(outFile, true))
{
MainDocumentPart mdp = doc.MainDocumentPart;
if (mdp.CustomXmlParts != null)
{
mdp.DeleteParts<CustomXmlPart>(mdp.CustomXmlParts);
}
CustomXmlPart cxp = mdp.AddCustomXmlPart(CustomXmlPartType.CustomXml);
FileStream fs = new FileStream(xmlPath, FileMode.Open);
cxp.FeedData(fs);
mdp.Document.Save();
}
}
}
}
I hope you fellow developers and office automation folks out there are able put this to good use!

Categories

Resources