Page Layout of Sections with Novacode DocX - c#

I am creating a document using Novacode DocX. I would like the entire document to be in landscape orienation, however I would also like to have several section breaks in the document. My code is laid out like this:
DocX doc = DocX.Create(fileName);
doc.PageLayout.Orientation = Novacode.Orientation.Landscape;
foreach (string page in pages)
{
doc.InsertSection(false);
Paragraph p = doc.InsertParagraph();
p.Append(page);
}
doc.PageLayout.Orientation = Novacode.Orientation.Landscape;
doc.SaveAs(Path.Combine(folderPath, fileName));
I've also tried adding doc.PageLayout.Orientation = Novacode.Orientation.Landscape inside the loop after doc.InsertSection(false) and I can't get anything past the first page to turn to landscape.
Is there a way around this?

See this answer from Delford Chaffin: https://stackoverflow.com/a/33178151/316578
"Creating the different sections as separate documents and inserting them into the main document worked well and solved all my problems."

Related

Calculate number of pages in docs file by dot net and C# and Syncfusion.DocIO.Net.Core Package

I have a .net Core 3.1 webapi.
I want to get the number of pages are in docs and doc file.
Am using the Syncfusion.DocIO.Net.Core package to perform operation on docs/doc file. But it does't provide feature to update stat of file and display only the PageCount: document.BuiltinDocumentProperties.PageCount;
This is not updated by files. Would you someone suggest me how i can calculate arithmetically.
You can get the page count from BuiltInProperties of the document using DocIO as below. It shows the page count in the document while creating the document using Microsoft Word application and also it still returns the same page count if we manipulate the document using DoIO.
int count = document.BuiltinDocumentProperties.PageCount;
If you want to get the page count, after manipulating the Word document using DocIO, we suggest you to convert the word document to PDF, and then you can retrieve the page count as like below.
WordDocument wordDocument = new WordDocument(fileStream, FormatType.Docx);
DocIORenderer render = new DocIORenderer();
//Sets Chart rendering Options.
render.Settings.ChartRenderingOptions.ImageFormat = ExportImageFormat.Jpeg;
//Converts Word document into PDF document
PdfDocument pdfDocument = render.ConvertToPDF(wordDocument);
int pageCount = pdfDocument.PageCount;
Since Word document is a flow document in which contents will not be preserved page by page; instead the contents will be preserved sequentially section by section. Each section may extend to various pages based on its contents like table, text, images etc.
Whereas Essential DocIO is a non-UI component that provides a full-fledged document object model to manipulate the Word document contents. Hence it is not feasible to get the page count directly from Word document using DocIO.
We have prepared the sample application to get the page counts from the word document and it can be downloaded from the below link.
https://www.syncfusion.com/downloads/support/directtrac/general/ze/GetPageCount16494613

How do I copy content from Word Document another with images and links?

I've had some problem when copying content from a Word document to another Word document.
The document where the information should end up in have a header.
So far I have managed to copy the content to the second document and not affecting the header.
However I can't figure out how to bind the relationships for links and Images.
This is my code so far:
public static void AddContentToTemplateCopy(
string sourceDocumentPath, string endDocumentPath)
{
using (WordprocessingDocument sourceDoc =
WordprocessingDocument.Open(sourceDocumentPath, false))
using (WordprocessingDocument endDoc =
WordprocessingDocument.Open(endDocumentPath, true))
{
var sourceMainPart = sourceDoc.MainDocumentPart;
var sourceBody = sourceMainPart.Document.Body;
var endSection = endDoc.MainDocumentPart.Document.Body.Elements<SectionProperties>();
var endDocMainPart = endDoc.MainDocumentPart;
var sourceBodyClone = sourceBody.CloneNode(true);
sourceBodyClone.ReplaceChild(endSection.FirstOrDefault().CloneNode(true), sourceBodyClone.Elements<SectionProperties>().FirstOrDefault());
endDocMainPart.Document.ReplaceChild(sourceBodyClone, endDocMainPart.Document.Body);
foreach (HyperlinkRelationship link in sourceMainPart.HyperlinkRelationships)
{
endDocMainPart.AddHyperlinkRelationship(link.Uri, link.IsExternal, link.Id);
}
}
I get the following Error : 'rId6' ID conflicts with the ID of an existing relationship for the specified source.
And the if i have a Image in the content it can't be displayed.
If I zip the document and look at the files in the package I can find the Image but for the same reason as the links the Relation
So my question is: How do I bind the links and Images with their "_rels" references? or how do I copy them so that it works..
This is a Relationship link when I have added the link by hand.
<Relationship Target="media/image1.jpg" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Id="rId11"/>
A picture to show that the link text is copied but have no formatting and that the image can't be displayed.
Thanks to the answer by JasonPlutext i managed to use OpenXML PowerTools (Version 2.2). Keep in mind that the .Net version is 3.5 when importing the project. You Might need to change it. (Supports Open XML 2.5 as well from what I've noticed)
Very simple to create new documents and take parts from old documents.
The code here is in my case where I want the formatting and content from one and then the Header from a template document. The order matters.
Hopefully this will save time for others with the same problem.
public static void AddContentToTemplateCopy(string templateDocumentPath,
string contentDocumentPath,
List<Source> sources,
string outName)
{
sources = new List<Source>()
{
new Source(new WmlDocument(contentDocumentPath),false),
new Source(new WmlDocument(templateDocumentPath),true),
};
DocumentBuilder.BuildDocument(sources, outName);
}
You might find it easier to try Eric White's document builder.

How can I use OpenXML SDK 2.5 to copy formulas from a word document?

I have to use OpenXML SDK 2.5 with C# to copy formulas from one word document then append them to another word document. I tried the below code, it ran successfully but when I tried to open the file, it said there's something wrong with the content. I opened it ignoring the warning but those formulas were not displayed. They are just blank blocks.
My code:
private void CreateNewWordDocument(string document, Exercise[] exercices)
{
using (WordprocessingDocument wordDoc = WordprocessingDocument.Create(document, WordprocessingDocumentType.Document))
{
// Set the content of the document so that Word can open it.
MainDocumentPart mainPart = wordDoc.AddMainDocumentPart();
SetMainDocumentContent(mainPart);
foreach (Exercise ex in exercices)
{
wordDoc.MainDocumentPart.Document.Body.AppendChild(ex.toParagraph().CloneNode(true));
}
wordDoc.MainDocumentPart.Document.Save();
}
}
// Set content of MainDocumentPart.
private void SetMainDocumentContent(MainDocumentPart part)
{
string docXml =
#"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>
<w:document xmlns:w=""http://schemas.openxmlformats.org/wordprocessingml/2006/main"">
<w:body><w:p><w:r><w:t>Exercise list!</w:t></w:r></w:p></w:body>
</w:document>";
using (Stream stream = part.GetStream())
{
byte[] buf = (new UTF8Encoding()).GetBytes(docXml);
stream.Write(buf, 0, buf.Length);
}
}
This happens because not everything that can be referenced in the paragraph is copied when you clone the paragraph. The Word XML format consists of multiple files some of which reference each other. If you copy the paragraph from one document to another you need to also copy any relationships that may exist.
The OpenXML Productivity Tool is useful for diagnosing errors like these. You can open a document with the tool and ask it to validate the document.
I created a test document that just contained a hyperlink and ran your code to copy the contents to another document. I too got an error when I attempted to load it using Word so I opened it in the Productivity Tool and saw the following output:
This shows that the hyperlink is stored as a relationship rather than inline in the paragraph and my new file references a relationship that doesn't exist. Unzipping the original file and the new file and comparing the two shows what is going on:
document.xml from original:
.rels of original
document.xml of generated file
.rels of generated file
Note that in the generated file the hyperlink references relationship rId5 but that doesn't exist in the generated documents relationship file.
It's worth noting that for simple source documents the code worked without issue as there are no relationships that require copying.
There are two ways that you can solve this. The easiest way is to only copy the text of the paragraph (you'll lose all styles, images, hyperlinks etc) but it is very simple. All you need to do is change
wordDoc.MainDocumentPart.Document.Body.AppendChild(ex.toParagraph().CloneNode(true));
for
Paragraph para = wordDoc.MainDocumentPart.Document.Body.AppendChild(new Paragraph());
Run run = para.AppendChild(new Run());
run.AppendChild(new Text(ex.toParagraph().InnerText));
The more complex (and perhaps proper) way of achieving it is to find the relationships and copy them to the new document as well. The code for doing that is probably beyond the scope of what I can write here but there is an interesting article on the subject here http://blogs.msdn.com/b/ericwhite/archive/2009/02/05/move-insert-delete-paragraphs-in-word-processing-documents-using-the-open-xml-sdk.aspx.
Essentially the author of that blog post is using the Powertools for OpenXML to find relationships and copy them from one document to another.

copy individual pages from word document to new document c#

I have a report that has hundreds of pages. I need to create extract each individual page from this document into a new document. I have found that this is possible using INTEROP, however I'm trying avoid installing MS Office on the server. I've been using ASPOSE for most of the operations, but this functionality is doesn't appear to be supported.
Is there a way to seperate pages of a document into individual files without having MS Office Installed?
Aspose.Words does not have layout information like pages or line numbers. It maintains DOM. But we have written some utility classes to achieve such behavior. They split the word document into multiple sections, such that each page becomes one separate section. After that, it is easy to copy individual pages.
String sourceDoc = dataDir + "source.docx";
String destinationtDoc = dataDir + "destination.docx";
// Initialize the Document instance with source and destination documents
Document doc = new Document(sourceDoc);
Document dstDoc = new Document();
// Remove the blank default page from new document
dstDoc.RemoveAllChildren();
PageNumberFinder finder = new PageNumberFinder(doc);
// Split nodes across pages
finder.SplitNodesAcrossPages(true);
// Get separate page sections
ArrayList pageSections = finder.RetrieveAllNodesOnPages(1, 5, NodeType.Section);
foreach (Section section in pageSections)
dstDoc.AppendChild(dstDoc.ImportNode(section, true));
dstDoc.LastSection.Body.LastParagraph.Remove();
dstDoc.Save(destinationtDoc);
The PageNumberFinder class can be downloaded from here.
PS. I am a Developer Evangelist at Aspose.

ITextSharp Multiple Page PDF from several templates

I have a requirement to generate a PDF from multiple different (Unknown page Sized PDF's)
Create a cover sheet from a template and write the text onto it.
Pull a PDF (Unknown page size) and append to the above 3) Repeat
until all required PDF's are attached
Step 1 is not a problem and this is working, so I have a a cover sheet PDF generated. I now need a way to append the additional PDF's as above. How can we achieve this using ITextSharp?
If you are trying to concatenate multiple PDF files into one you may take a look at the following post.
I found a simple way to do this, I found something called PDFCopy in ITextSharp
void MergePdfStreams(List<Stream> Source, Stream Dest)
{
var copy = new PdfCopyFields(Dest);
foreach (Stream source in Source)
{
var reader = new PdfReader(source);
copy.AddDocument(reader);
}
copy.Close();
}
Source : Is there a straight forward way to append one PDF doc to another using iTextSharp?

Categories

Resources