I get count of pages in next code:
using DocumentFormat.OpenXml.Packaging;
WordprocessingDocument doc = WordprocessingDocument.Open( #"D:\2pages.docx", false );
Console.WriteLine(
doc.ExtendedFilePropertiesPart.Properties.Pages.InnerText.ToString()
);
can I get in this way height and width of file?
or in another way but without using office.
Aspose.Word (which is not free) has these things built in:
https://docs.aspose.com/display/wordsnet/Changing+Page+Setup+for+Whole+Document+using+Aspose.Words
Document doc = new Document();
// This truly makes the document empty. No sections (not possible in Microsoft Word).
doc.RemoveAllChildren();
// Create a new section node.
// Note that the section has not yet been added to the document,
// but we have to specify the parent document.
Section section = new Section(doc);
// Append the section to the document.
doc.AppendChild(section);
// Lets set some properties for the section.
section.PageSetup.SectionStart = SectionStart.NewPage;
section.PageSetup.PaperSize = PaperSize.Letter;
Someone had a similar problem and this is the discussion on SO (but with OpenXML):
Change Page size of Wor Document using Open Xml SDK 2.0
Maybe you can deduct your answer from this.
Please use PageSetup.PageHeight and PageSetup.PageWidth properties to get the page's height and width. Hope this helps you.
Document doc = new Document(MyDir + "input.docx");
Console.WriteLine(doc.FirstSection.PageSetup.PageHeight);
Console.WriteLine(doc.FirstSection.PageSetup.PageWidth);
I work with Aspose as Developer Evangelist.
Related
I am trying to add a custom font to my pdf output using the nuget package MVCRazorToPdf but I am having trouble with how to do this as the documentation for iTextSharp isn't great and all seems to be outdated.
The current code I have for creating the pdf is:
return new PdfActionResult(
"test.cshtml",
new TestModel(),
(writer, document) =>
{
FontFactory.Register(HostingEnvironment.MapPath("~/content/fonts/vegur-regular-webfont.ttf"), "VegurRegular");
});
Where writer is a PdfWriter and document is a Document
All the examples of using the FontFactory show that you need to use the XmlWorker but I don't have access to that, so I was wondering if there was any way to change the documents font using the writer or document?
I've seen that there is the document.HtmlStyleClass property but can't find anything about how to use this anywhere.
Any help with this would be greatly appreciated
MVCRazorToPdf is a very, very simple wrapper around iTextSharp's XMLWorker and uses the even simpler XMLWorkerHelper with all defaults to do its work. If you look at the source you'll see this:
document.Open();
using (var reader = new StringReader(RenderRazorView(context, viewName)))
{
XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, reader);
document.Close();
output = workStream.ToArray();
}
If you're dead-set on using the NuGet version then you're stuck with this implementation and you're not going to be able to register a custom font.
However, there's an open issue regarding this that includes a fix so if you're willing to compile from source you can apply that change and you should be all set.
If you want to go one step further I'd recommend reading this great post that shows how simple parsing HTML with iTextSharp is as well Bruno's post here that shows how to register fonts.
EDIT
As per the post in the includes a fix link (just in case the link breaks in future), change the above using statement to:
using (var reader = new MemoryStream(Encoding.UTF8.GetBytes(RenderRazorView(context, viewName))))
{
XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, reader, null, FontFactory.FontImp as IFontProvider);
document.Close();
output = workStream.ToArray();
}
And then the font factory as registered in the question above will work when using style="font-family:VegurRegular;"
I'm using Open XML (DocumentFormat.OpenXml nuget package) to generating a docx file. Here is my approach:
I have a file, named template.docx. In this file I have a Cover Page and a blank page which has header, footer, and a background image. Anyway, I first open the document, then append some text to the document, then close it.
In the other hand, I have a file named template-back.docx which I want to append that at the end of modified document (template.docx) above.
I'm able to do that, by using this snippet:
public static void MergeDocumentWithPagebreak(string sourceFile, string destinationFile, string altChunkID) {
using (var myDoc = WordprocessingDocument.Open(sourceFile, true)) {
var mainPart = myDoc.MainDocumentPart;
//Append page break
var para = new Paragraph(new Run((new Break() { Type = BreakValues.Page })));
mainPart.Document.Body.InsertAfter(para, mainPart.Document.Body.LastChild);
//Append file
var chunk = mainPart.AddAlternativeFormatImportPart(
AlternativeFormatImportPartType.WordprocessingML, altChunkID);
using (var fileStream = File.Open(destinationFile, FileMode.Open))
chunk.FeedData(fileStream);
var altChunk = new AltChunk{
Id = altChunkID
};
mainPart.Document
.Body
.InsertAfter(altChunk, mainPart.Document.Body.Elements<Paragraph>().Last());
mainPart.Document.Save();
}
}
But, when I do that, the header, footer, and background image, are applied to the last page. I want to be able to exclude last page from getting those designs. I want it to be clean, simple and white. But googling the issue, had nothing to help. Do you have any idea please? Thanks in advance.
P.S.
The original article about merging documents here:
It's a little bit tricky, but not so complicated.
First you have to understand how word works:
By default, a word document is one section, and this one section share header and footer. If you want differents header / footer, you have to create a break at the end of a page to indicate "the next page is a new section".
Once a new section is create, you must indicate "the new section don't share the same header / footer"
Some documentation on "how to create different header in word". http://www.techrepublic.com/blog/microsoft-office/accommodate-different-headers-and-footers-in-a-word-document/
If we translate to your code, before inserting your document at the end of the other, you have to:
Create a section break
Inserting a new Header / footer in this section (an empty one)
Insert your new document in the new section
To create the new header, some other documentation: https://msdn.microsoft.com/en-us/library/office/cc546917.aspx
Trick: if the document you insert don't contain header / footer, create empty ones and recopy them
Information: I tried to delete the <w:headerReference r:id="rIdX" w:type="default"/> or to set the r:id to 0 but it don't work. Create an empty header is the fastest way
Replace your Page break with the following code
Paragraph PageBreakParagraph = new Paragraph(new DocumentFormat.OpenXml.Wordprocessing.Run(new DocumentFormat.OpenXml.Wordprocessing.Break() { Type = BreakValues.Page }));
I also saw that you are inserting after the last child which is not essential same as Appending but works well for you! Use this instead.
wordprocessingDocument.MainDocumentPart.Document.Body.Append(PageBreakParagraph)
You need to add the section break to the section properties. You then need to append the section properties to the paragraph properties. Followed by appending the paragraph properties to a paragraph.
Paragraph paragraph232 = new Paragraph();
ParagraphProperties paragraphProperties220 = new ParagraphProperties();
SectionProperties sectionProperties1 = new SectionProperties();
SectionType sectionType1 = new SectionType(){ Val = SectionMarkValues.NextPage };
sectionProperties1.Append(sectionType1);
paragraphProperties220.Append(sectionProperties1);
paragraph232.Append(paragraphProperties220);
//Replace your last but one line with this one.
mainPart.Document
.Body
.Append(altChunk);
The resulting Open XML is:
<w:p>
<w:pPr>
<w:sectPr>
<w:type w:val="nextPage" />
</w:sectPr>
</w:pPr>
</w:p>
The Easiest way to do it is to actually create the document in word and then open in it in the Open XML Productivity Tool, you can reflect the code and see what C# code would generate the various Open XML elements you are trying to achieve. Hope this helps!
I'm looking for an example to store building blocks in a word document with the Aspose Word Api. And I want to use these building blocks exclusiv in this document.
Has anybody an idea, how this can be realized?
Greetings
Tobi.
If you have MS Word 2013 installed on your machine, you'll most likely find a Word document 'Built-In Building Blocks.dotx' at the following location:
C:\Users\Awais\AppData\Roaming\Microsoft\Document Building Blocks\1033\15\Built-In Building Blocks.dotx
The predefined built-in building blocks entries that ship with Word are stored in above template document. Using Aspose.Words, you can extract any building block from it, paste inside another Word document and save new document for future use.
GlossaryDocument class in Aspose.Words represents such Building Blocks. Please try using the following code:
Document docBuildingBlocks = new Document(MyDir + #"Building Blocks.dotx");
Document doc = new Document(MyDir + #"input.docx");
GlossaryDocument glossaryDocument = docBuildingBlocks.GlossaryDocument;
foreach (BuildingBlock buildingBlock in glossaryDocument.BuildingBlocks)
{
if (buildingBlock.Gallery.ToString().StartsWith("CoverPage"))
{
Section sec = (Section)buildingBlock.FirstChild;
doc.AppendChild(doc.ImportNode(sec, true));
}
}
doc.Save(MyDir + #"15.6.0.docx");
Hope, this helps.
I work with Aspose as Developer Evangelist.
I am attempting to merge several Word documents together into a single Word document. I am using the AltChunk capability from Microsoft's OpenXML SDK 2.5. The final report needs to be in landscape orientation, thus we have put each component document into landscape mode. I am merging the documents using the following code.
for (int i = 0; i < otherDocs.Length; i++)
{
using (var headerDoc = WordprocessingDocument.Open(headerPath, true))
{
var mainPart = headerDoc.MainDocumentPart;
string altChunkId = "AltChunkId" + i;
var chunk = mainPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.WordprocessingML, altChunkId);
using (var fileStream = File.Open(otherDocs[i], FileMode.Open))
{
chunk.FeedData(fileStream);
}
var altChunk = new AltChunk();
altChunk.Id = altChunkId;
mainPart.Document.Body.InsertAfter(altChunk, mainPart.Document.Body.Elements<Paragraph>().Last());
mainPart.Document.Save();
DocumentWriter.SetPrintOrientation(headerDoc, PageOrientationValues.Landscape);
headerDoc.Close();
}
}
When I run this code, the final output document has a mix of landscape and portrait orientation if the component documents each have at least one section break.
The DocumentWriter.SetPrintOrientation() method is implemented according to instructions from MSDN. It seems to have no effect on the actual orientation of the document. I have also examined the underlying XML files, and all "orient" attributes are set to landscape.
Is there some configuration option or API call I can use to ensure the final document will have landscape orientation across all sections?
An OpenXML Word document is a zipped collections of XML documents that define its content, formatting, and metadata. When merging Word documents together using AddAlternativeFormatImportPart, the Word documents being merged into the original document (AltChunks) are copied into the zip archive, and XML elements referencing the documents are added into the XML document definition. Then, the next time anyone opens the resulting document in Microsoft Word (or any other OpenXML compatible document editor), the application handles merging in the AltChunks. In this case, Microsoft Word 2010 (the version we are using) has a bug causing Word to ignore some formatting information defined in Word document sections. One of these pieces of information is orientation, making the AltChunk approach ineffective at preserving orientation information.
Instead, we used DocumentBuilder from the OpenXml Power Tools project. This resulted in much simpler code that solved our problem in two lines:
var sourceList = documentPaths.Select(doc => new Source(new WmlDocument(doc), true)).ToList();
DocumentBuilder.BuildDocument(sourceList, outputPath);
I'm using MigraDoc to programatically generate a PDF file with text, images and tables.
I need to set Document Orientation (for all pages) in the document object to Landscape.
So I tried the following.
document.DefaultPageSetup.Orientation = Orientation.Landscape;
But I get the following debug assertion error.
---------------------------
Assertion Failed: Abort=Quit, Retry=Debug, Ignore=Continue
---------------------------
DefaultPageSetup must not be modified
If I click Ignore, it goes through and the Orientation is indeed Landscape.
However, I want to make sure I am doing this the right way.
So the question is, how do I set the document orientation for all pages in a Document using the MigraDoc library?
Here's the rest of the code (so it helps you get the context)
using System.Runtime.Remoting.Messaging;
using MigraDoc.DocumentObjectModel;
namespace MyNamespace.PdfReports
{
class Documents
{
public static Document CreateDocument()
{
// Create a new MigraDoc document
Document document = new Document();
document.Info.Title = "The Title";
document.Info.Subject = "The Subject";
document.Info.Author = "Shiva";
document.DefaultPageSetup.Orientation = Orientation.Landscape;
Many thanks!
-Shiva
UPDATE:
SOLUTION: Here's the working code, based on Thomas' answer below (for the benefit of others who maybe looking for this solution).
// Create a new MigraDoc document
Document document = new Document();
//...
//......
PageSetup pageSetup = document.DefaultPageSetup.Clone();
// set orientation
pageSetup.Orientation = Orientation.Landscape;
// ... set other page setting you want here...
Assign DefaultPageSetup.Clone() to the PageFormat of your section and modify that.
Then you modify a copy of the default settings and no assertion will fail.
With your approach, all documents would default to landscape - not just the document you set it for.
This answer applies to MigraDoc only as only MigraDoc uses DefaultPageSetup.
See this post in the PDFsharp forum where Clone() is used to create a copy of the DefaultPageSetup: