I tried to convert png to xps. I fallow this answer .
My code:
XpsDocument xpsDocument = new XpsDocument(#"C:\pathRoot\fileName.xps", FileAccess.ReadWrite);
XpsDocumentWriter xpsDocumentWriter = XpsDocument.CreateXpsDocumentWriter(xpsDocument);
xpsDocumentWriter.Write(#"C:\pathRoot\fileName.png");
Here I got an exception
System.IO.FileFormatException: 'File contains corrupted data.'
I assumed that answer's author by saying "YourImageYouWishToWrite" means a path to png file like 'C:\pathRoot\fileName.png'. Or I am getting it completely wrong.
the easiest way to do this through printing all Images into Microsoft XPS Writer Printer , then you can merge the output individual XPS files , like :
public void MergeXpsDocument(string outputXPS, string[] ListOfXPS)
{
if (File.Exists(outputXPS))
{
File.Delete(outputXPS);
}
XpsDocument[] XpsFiles = new XpsDocument[ListOfXPS.Length];
for (int i = 0; i < ListOfXPS.Length; i++)
{
XpsDocument xpsFile = new XpsDocument(ListOfXPS[i], FileAccess.Read);
XpsFiles[i] = xpsFile;
}
XpsDocument tempPackage = new XpsDocument(outputXPS, FileAccess.ReadWrite);
XpsDocumentWriter xpsDocWriter = XpsDocument.CreateXpsDocumentWriter(tempPackage);
FixedDocumentSequence fixedDocSequence = new FixedDocumentSequence();
foreach (XpsDocument XPSdoc in XpsFiles)
{
FixedDocumentSequence fixedDocSeq = XPSdoc.GetFixedDocumentSequence();
foreach (DocumentReference sourceSequence in fixedDocSeq.References)
{
DocumentReference docRef = new DocumentReference();
docRef.Source = sourceSequence.Source;
(docRef as IUriContext).BaseUri = (sourceSequence as IUriContext).BaseUri;
FixedDocument fd = docRef.GetDocument(true);
docRef.SetDocument(fd);
fixedDocSequence.References.Add(docRef);
}
}
xpsDocWriter.Write(fixedDocSequence);
tempPackage.Close();
Related
I am having issues converting my files to pdf. I am completely new to C# (coming from java) and I am trying to build an application that first prints out a log into a text file then converts it to a PDF. If you know a good resource or example please point me in the right direction without judgement. Thank you!
createPDF(myFileString);
void createPDF(string txtFile)
{
string line = null;
System.IO.TextReader readFile = new StreamReader(myFileString);
int yPoint = 0;
PdfDocument pdf = new PdfDocument();
pdf.Info.Title = "TXT to PDF";
PdfPage pdfPage = pdf.AddPage();
XGraphics graph = XGraphics.FromPdfPage(pdfPage);
while (true)
{
line = readFile.ReadLine();
if (line == null)
{
break; // TODO: might not be correct. Was : Exit While
}
else
{
yPoint = yPoint + 40;
}
}
string pdfFilename = "txttopdf.pdf";
pdf.Save(pdfFilename);
readFile.Close();
readFile = null;
Process.Start(pdfFilename);
}
In short: I would like to insert the content of a docx that contains images and bullets in another docx.
My problem: I used two approaches:
Manual merge
Altchunk
With both of them I got a corrupted word document as result.
If I remove the images from the docx that I would like to insert in another one, the result docx is OK.
My code:
Manual merge (thanks to https://stackoverflow.com/a/48870385/10075827):
private static void ManualMerge(string firstPath, string secondPath, string resultPath)
{
if (!System.IO.Path.GetFileName(firstPath).StartsWith("~$"))
{
File.Copy(firstPath, resultPath, true);
using (WordprocessingDocument result = WordprocessingDocument.Open(resultPath, true))
{
using (WordprocessingDocument secondDoc = WordprocessingDocument.Open(secondPath, false))
{
OpenXmlElement p = result.MainDocumentPart.Document.Body.Descendants<Paragraph>().Last();
foreach (var e in secondDoc.MainDocumentPart.Document.Body.Elements())
{
var clonedElement = e.CloneNode(true);
clonedElement.Descendants<DocumentFormat.OpenXml.Drawing.Blip>().ToList().ForEach(blip =>
{
var newRelation = result.CopyImage(blip.Embed, secondDoc);
blip.Embed = newRelation;
});
clonedElement.Descendants<DocumentFormat.OpenXml.Vml.ImageData>().ToList().ForEach(imageData =>
{
var newRelation = result.CopyImage(imageData.RelationshipId, secondDoc);
imageData.RelationshipId = newRelation;
});
result.MainDocumentPart.Document.Body.Descendants<Paragraph>().Last();
if (clonedElement is Paragraph)
{
p.InsertAfterSelf(clonedElement);
p = clonedElement;
}
}
}
}
}
}
public static string CopyImage(this WordprocessingDocument newDoc, string relId, WordprocessingDocument org)
{
var p = org.MainDocumentPart.GetPartById(relId) as ImagePart;
var newPart = newDoc.MainDocumentPart.AddPart(p);
newPart.FeedData(p.GetStream());
return newDoc.MainDocumentPart.GetIdOfPart(newPart);
}
Altchunk merge (from http://www.karthikscorner.com/sharepoint/use-altchunk-document-assembly/):
private static void AltchunkMerge(string firstPath, string secondPath, string resultPath)
{
WordprocessingDocument mainDocument = null;
MainDocumentPart mainPart = null;
var ms = new MemoryStream();
#region Prepare - consuming application
byte[] bytes = File.ReadAllBytes(firstPath);
ms.Write(bytes, 0, bytes.Length);
mainDocument = WordprocessingDocument.Open(ms, true);
mainPart = mainDocument.MainDocumentPart;
#endregion
#region Document to be imported
FileStream fileStream = new FileStream(secondPath, FileMode.Open);
#endregion
#region Merge
AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.WordprocessingML, "AltChunkId101");
chunk.FeedData(fileStream);
var altChunk = new AltChunk(new AltChunkProperties() { MatchSource = new MatchSource() { Val = new OnOffValue(true) } });
altChunk.Id = "AltChunkId101";
mainPart.Document.Body.InsertAfter(altChunk, mainPart.Document.Body.Elements<Paragraph>().Last());
mainPart.Document.Save();
#endregion
#region Mark dirty
var listOfFieldChar = mainPart.Document.Body.Descendants<FieldChar>();
foreach (FieldChar current in listOfFieldChar)
{
if (string.Compare(current.FieldCharType, "begin", true) == 0)
{
current.Dirty = new OnOffValue(true);
}
}
#endregion
#region Save Merged Document
mainPart.DocumentSettingsPart.Settings.PrependChild(new UpdateFieldsOnOpen() { Val = new OnOffValue(true) });
mainDocument.Close();
FileStream file = new FileStream(resultPath, FileMode.Create, FileAccess.Write);
ms.WriteTo(file);
file.Close();
ms.Close();
#endregion
}
I spent hours searching for a solution and the most common one I found was to use altchunk. So why is it not working in my case?
If you are able to use the Microsoft.Office.Interop.Word namespace, and able to put a bookmark in the file you want to merge into, you can take this approach:
using Microsoft.Office.Interop.Word;
...
// merge by putting second file into bookmark in first file
private static void NewMerge(string firstPath, string secondPath, string resultPath, string firstBookmark)
{
var app = new Application();
var firstDoc = app.Documents.Open(firstPath);
var bookmarkRange = firstDoc.Bookmarks[firstBookmark];
// Collapse the range to the end, as to not overwrite it. Unsure if you need this
bookmarkRange.Collapse(WdCollapseDirection.wdCollapseEnd);
// Insert into the selected range
// use if relative path
bookmarkRange.InsertFile(Environment.CurrentDirectory + secondPath);
// use if absolute path
//bookmarkRange.InsertFile(secondPath);
}
Related:
C#: Insert and indent bullet points at bookmark in word document using Office Interop libraries
Hi i'm trying to read various pdf files with ItextSharp.dll, some of them throws me an exception when I try to read it. the exception is this: "The document has no page root (meaning: it's an invalid PDF).". I made some tests in the Merge example, in the Itext web page(Merge-Example) and these are successful. So, can someone guide me to see what am I doing wrong?
This is my code:
public void MergeFiles(String[] strFiles, String strFileresult)
{
Document document = new Document(); ;
PdfCopy copy;
copy = new PdfCopy(document, new FileStream(strFileresult, FileMode.Create));
document.Open();
PdfReader[] reader = new PdfReader[3];
for (int i = 0; i < strFiles.Count(); i++)
{
reader[i] = new PdfReader(strFiles[i]);
copy.AddDocument(reader[i]);
}
document.Close();
for (int i = 0; i < reader.Count(); i++)
{
reader[i].Close();
}
}
I'm not sure what's causing your exact problem but once we get rid of the unnecessary internal arrays and switch to the using pattern to get automatic cleanup everything works just fine.
public void MergeFiles(string[] strFiles, String strFileresult) {
using( var document = new Document()) {
using (var copy = new PdfCopy(document, new FileStream(strFileresult, FileMode.Create))) {
document.Open();
foreach( var file in strFiles) {
using (var reader = new PdfReader(file)) {
copy.AddDocument(reader);
}
}
document.Close();
}
}
}
I am Creating a word document through the c# with the use of OpenXMl sdk.
I am converting all my html page to word document but while converting i am giving a absolute address for my images and after converting it is coming perfectly in my system but when i am trying to take this document to other system the Images are Not Coming there.
I checked the media Directory all images are there but with different Name.
my document is converted but I am Using this mathod.
using (WordprocessingDocument myDoc = WordprocessingDocument.Open(documentPath, true))
{
XNamespace w =
"http://schemas.openxmlformats.org/wordprocessingml/2006/main";
XNamespace r =
"http://schemas.openxmlformats.org/officeDocument/2006/relationships";
string altChunkId = "AltChunkId1";
MainDocumentPart mainPart = myDoc.MainDocumentPart;
AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart("application/xhtml+xml", altChunkId);
using (Stream chunkStream = chunk.GetStream(FileMode.Create, FileAccess.Write))
using (StreamWriter stringStream = new StreamWriter(chunkStream))
stringStream.Write(html);
XElement altChunk = new XElement(w + "altChunk",
new XAttribute(r + "id", altChunkId)
);
XDocument mainDocumentXDoc = GetXDocument(myDoc);
mainDocumentXDoc.Root
.Element(w + "body")
.Elements(w + "p")
.Last()
.AddAfterSelf(altChunk);
SaveXDocument(myDoc, mainDocumentXDoc);
}
private static XDocument GetXDocument(WordprocessingDocument myDoc)
{
// Load the main document part into an XDocument
XDocument mainDocumentXDoc;
using (Stream str = myDoc.MainDocumentPart.GetStream())
using (XmlReader xr = XmlReader.Create(str))
mainDocumentXDoc = XDocument.Load(xr);
return mainDocumentXDoc;
}
private static void SaveXDocument(WordprocessingDocument myDoc,
XDocument mainDocumentXDoc)
{
// Serialize the XDocument back into the part
using (Stream str = myDoc.MainDocumentPart.GetStream(
FileMode.Create, FileAccess.Write))
using (XmlWriter xw = XmlWriter.Create(str))
mainDocumentXDoc.Save(xw);
}
and this will generate a afchunk.dat file which is showing in the content and the Absolute path.
Basically i doesn't want to create a file through all coding i just want to convert the .html to .docx file .
so can any one tell me how can i convert without getting error in html.
Is there a reason you aren't embedding the images? Here's a link with sample code to show you how.
http://msdn.microsoft.com/en-us/library/bb497430.aspx
Try to create a DocumentResource (Item->Add new) and associate the images there.
Call the Document
using (Stream imgStream = ip.GetStream())
{
System.Drawing.Bitmap logo = DocumentResources._default;
logo.Save(imgStream, System.Drawing.Imaging.ImageFormat.Jpeg);
}
Drawing drawing = BuildImage(imageRelationshipID, "_default.jpg", 200, 30);
And create the method to build image in the header or footer;
private static Drawing BuildImage(string imageRelationshipID, string imageName, int pixelWidth, int pixelHeight)
{
int emuWidth = (int)(pixelWidth * EMU_PER_PIXEL);
int emuHeight = (int)(pixelHeight * EMU_PER_PIXEL);
Drawing drawing = new Drawing();
d.Wordprocessing.Inline inline = new d.Wordprocessing.Inline { DistanceFromTop = 0, DistanceFromBottom = 0, DistanceFromLeft = 0, DistanceFromRight = 0 };
d.Wordprocessing.Anchor anchor = new d.Wordprocessing.Anchor();
d.Wordprocessing.SimplePosition simplePos = new d.Wordprocessing.SimplePosition { X = 0, Y = 0 };
d.Wordprocessing.Extent extent = new d.Wordprocessing.Extent { Cx = emuWidth, Cy = emuHeight };
d.Wordprocessing.DocProperties docPr = new d.Wordprocessing.DocProperties { Id = 1, Name = imageName };
d.Graphic graphic = new d.Graphic();
d.GraphicData graphicData = new d.GraphicData { Uri = GRAPHIC_DATA_URI };
d.Pictures.Picture pic = new d.Pictures.Picture();
d.Pictures.NonVisualPictureProperties nvPicPr = new d.Pictures.NonVisualPictureProperties();
d.Pictures.NonVisualDrawingProperties cNvPr = new d.Pictures.NonVisualDrawingProperties { Id = 2, Name = imageName };
d.Pictures.NonVisualPictureDrawingProperties cNvPicPr = new d.Pictures.NonVisualPictureDrawingProperties();
d.Pictures.BlipFill blipFill = new d.Pictures.BlipFill();
d.Blip blip = new d.Blip { Embed = imageRelationshipID };
d.Stretch stretch = new d.Stretch();
d.FillRectangle fillRect = new d.FillRectangle();
d.Pictures.ShapeProperties spPr = new d.Pictures.ShapeProperties();
d.Transform2D xfrm = new d.Transform2D();
d.Offset off = new d.Offset { X = 0, Y = 0 };
d.Extents ext = new d.Extents { Cx = emuWidth, Cy = emuHeight };
d.PresetGeometry prstGeom = new d.PresetGeometry { Preset = d.ShapeTypeValues.Rectangle };
d.AdjustValueList avLst = new d.AdjustValueList();
xfrm.Append(off);
xfrm.Append(ext);
prstGeom.Append(avLst);
stretch.Append(fillRect);
spPr.Append(xfrm);
spPr.Append(prstGeom);
blipFill.Append(blip);
blipFill.Append(stretch);
nvPicPr.Append(cNvPr);
nvPicPr.Append(cNvPicPr);
pic.Append(nvPicPr);
pic.Append(blipFill);
pic.Append(spPr);
graphicData.Append(pic);
graphic.Append(graphicData);
inline.Append(extent);
inline.Append(docPr);
inline.Append(graphic);
drawing.Append(inline);
return drawing;
}
i have the code for saving a gridview as an html file using a savefiledialog. i want to save it to a specific path (without using the savefiledialog)... how can i do that?
here's my code:
SaveFileDialog dialog = new SaveFileDialog();
dialog.DefaultExt = "*.html";
dialog.Filter = "WORD Document (*.html)|*.html";
if (dialog.ShowDialog() == true)
{
RadDocument document = CreateDocument(rgvReportData);
document.LayoutMode = DocumentLayoutMode.Paged;
document.Measure(RadDocument.MAX_DOCUMENT_SIZE);
document.Arrange(new RectangleF(PointF.Empty, document.DesiredSize));
document.SectionDefaultPageMargin = new Telerik.Windows.Documents.Layout.Padding(2, 2, 2, 2);
document.SectionDefaultPageOrientation = PageOrientation.Landscape;
HtmlFormatProvider provider = new HtmlFormatProvider();
using (Stream output = dialog.OpenFile())
{
provider.Export(document, output);
}
}
how can i sve it without using a savefiledialog?
using(StreamWriter output = new StreamWriter("path\to\your\file")) {
provider.Export(document, output);
}
will do the same thing, but to a specific path. You can read more on file access on MSDN.
String fileName = "youfilename.html"; // give the full path if required
RadDocument document = CreateDocument(rgvReportData);
document.LayoutMode = DocumentLayoutMode.Paged;
document.Measure(RadDocument.MAX_DOCUMENT_SIZE);
document.Arrange(new RectangleF(PointF.Empty, document.DesiredSize));
document.SectionDefaultPageMargin = new Telerik.Windows.Documents.Layout.Padding(2, 2, 2, 2);
document.SectionDefaultPageOrientation = PageOrientation.Landscape;
HtmlFormatProvider provider = new HtmlFormatProvider();
Stream output = File.Open(filename, FileMode.Open, FileAccess.ReadWrite);
provider.Export(document, output);
}
using (var output = new FileStream("path", FileMode.Create, FileAccess.Write))
{
provider.Export(document, output);
}
OpenFileDialog displays the specific path that you have choosen.
You could set the path of the SaveFileDialog, is not necessary to show the dialog like dialog.ShowDialog(), you have just to set the path like dialog.Filename = "file name".
And replace it like :
SaveFileDialog dialog = new SavefileDialog();
dialog.FileName = "path"; // like "C:\\someFolder\\someFile.html"
You could try it