Wednesday, 13 January 2016 07:59
How to Set a custom property in a word processing document
class Program { static void Main(string[] args) { const string fileName = "SetCustomProperty.docx"; Console.WriteLine("Manager = " + SetCustomProperty(fileName, "Manager", "Peter", PropertyTypes.Text)); Console.WriteLine("ReviewDate = " + SetCustomProperty(fileName, "ReviewDate", DateTime.Parse("12/21/2010"), PropertyTypes.DateTime)); } public enum PropertyTypes : int { YesNo, Text, DateTime, NumberInteger, NumberDouble } public static string SetCustomProperty( string fileName, string propertyName, object propertyValue, PropertyTypes propertyType) { // Given a document name, a property name/value, and the property type, // add a custom property to a document. The method returns the original // value, if it existed. string returnValue = null; var newProp = new CustomDocumentProperty(); bool propSet = false; // Calculate the correct type. switch (propertyType) { case PropertyTypes.DateTime: // Be sure you were passed a real date, // and if so, format in the correct way. // The date/time value passed in should // represent a UTC date/time. if ((propertyValue) is DateTime) { newProp.VTFileTime = new VTFileTime(string.Format("{0:s}Z", Convert.ToDateTime(propertyValue))); propSet = true; } break; case PropertyTypes.NumberInteger: if ((propertyValue) is int) { newProp.VTInt32 = new VTInt32(propertyValue.ToString()); propSet = true; } break; case PropertyTypes.NumberDouble: if (propertyValue is double) { newProp.VTFloat = new VTFloat(propertyValue.ToString()); propSet = true; } break; case PropertyTypes.Text: newProp.VTLPWSTR = new VTLPWSTR(propertyValue.ToString()); propSet = true; break; case PropertyTypes.YesNo: if (propertyValue is bool) { // Must be lowercase. newProp.VTBool = new VTBool( Convert.ToBoolean(propertyValue).ToString().ToLower()); propSet = true; } break; } if (!propSet) { // If the code was not able to convert the // property to a valid value, throw an exception. throw new InvalidDataException("propertyValue"); } // Now that you have handled the parameters, start // working on the document. newProp.FormatId = "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}"; newProp.Name = propertyName; using (var document = WordprocessingDocument.Open(fileName, true)) { var customProps = document.CustomFilePropertiesPart; if (customProps == null) { // No custom properties? Add the part, and the // collection of properties now. customProps = document.AddCustomFilePropertiesPart(); customProps.Properties = new DocumentFormat.OpenXml.CustomProperties.Properties(); } var props = customProps.Properties; if (props != null) { // This will trigger an exception if the property's Name // property is null, but if that happens, the property is damaged, // and probably should raise an exception. var prop = props.Where( p => ((CustomDocumentProperty)p).Name.Value == propertyName).FirstOrDefault(); // Does the property exist? If so, get the return value, // and then delete the property. if (prop != null) { returnValue = prop.InnerText; prop.Remove(); } // Append the new property, and // fix up all the property ID values. // The PropertyId value must start at 2. props.AppendChild(newProp); int pid = 2; foreach (CustomDocumentProperty item in props) { item.PropertyId = pid++; } props.Save(); } } return returnValue; } }
Published in
OpenXML
Wednesday, 13 January 2016 07:58
How to Retrieve comments from a word processing document
class Program { static void Main(string[] args) { string fileName = "OpenXML.docx"; GetCommentsFromDocument(fileName); } public static void GetCommentsFromDocument(string fileName) { using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(fileName, false)) { WordprocessingCommentsPart commentsPart = wordDoc.MainDocumentPart.WordprocessingCommentsPart; if (commentsPart != null && commentsPart.Comments != null) { foreach (Comment comment in commentsPart.Comments.Elements()) { Console.WriteLine(comment.InnerText); } } } Console.ReadLine(); } }
Published in
OpenXML
Wednesday, 13 January 2016 07:57
How to Remove the headers and footers
class Program { static void Main(string[] args) { RemoveHeadersAndFooters("HeadersAndFooters.docx"); } // Remove all of the headers and footers from a document. public static void RemoveHeadersAndFooters(string filename) { // Given a document name, remove all of the headers and footers // from the document. using (WordprocessingDocument doc = WordprocessingDocument.Open(filename, true)) { // Get a reference to the main document part. var docPart = doc.MainDocumentPart; // Count the header and footer parts and continue if there // are any. if (docPart.HeaderParts.Count() > 0 || docPart.FooterParts.Count() > 0) { // Remove the header and footer parts. docPart.DeleteParts(docPart.HeaderParts); docPart.DeleteParts(docPart.FooterParts); // Get a reference to the root element of the main // document part. Document document = docPart.Document; // Remove all references to the headers and footers. // First, create a list of all descendants of type // HeaderReference. Then, navigate the list and call // Remove on each item to delete the reference. var headers = document.Descendants().ToList(); foreach (var header in headers) { header.Remove(); } // First, create a list of all descendants of type // FooterReference. Then, navigate the list and call // Remove on each item to delete the reference. var footers = document.Descendants().ToList(); foreach (var footer in footers) { footer.Remove(); } // Save the changes. document.Save(); } } } }
Published in
OpenXML
Wednesday, 13 January 2016 07:55
How to Insert a picture into a word processing document
class Program { static void Main(string[] args) { string document = "Word9.docx"; string fileName = "test.jpg"; InsertAPicture(document, fileName); } public static void InsertAPicture(string document, string fileName) { using (WordprocessingDocument wordprocessingDocument =WordprocessingDocument.Open(document, true)) { MainDocumentPart mainPart = wordprocessingDocument.MainDocumentPart; ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Jpeg); using (FileStream stream = new FileStream(fileName, FileMode.Open)) { imagePart.FeedData(stream); } AddImageToBody(wordprocessingDocument, mainPart.GetIdOfPart(imagePart)); } } private static void AddImageToBody(WordprocessingDocument wordDoc, string relationshipId) { // Define the reference of the image. var element = new Drawing( new DW.Inline( new DW.Extent() { Cx = 990000L, Cy = 792000L }, new DW.EffectExtent() { LeftEdge = 0L, TopEdge = 0L, RightEdge = 0L, BottomEdge = 0L }, new DW.DocProperties() { Id = (UInt32Value)1U, Name = "Picture 1" }, new DW.NonVisualGraphicFrameDrawingProperties( new A.GraphicFrameLocks() { NoChangeAspect = true }), new A.Graphic( new A.GraphicData( new PIC.Picture( new PIC.NonVisualPictureProperties( new PIC.NonVisualDrawingProperties() { Id = (UInt32Value)0U, Name = "New Bitmap Image.jpg" }, new PIC.NonVisualPictureDrawingProperties()), new PIC.BlipFill( new A.Blip( new A.BlipExtensionList( new A.BlipExtension() { Uri = "{28A0092B-C50C-407E-A947-70E740481C1C}" }) ) { Embed = relationshipId, CompressionState = A.BlipCompressionValues.Print }, new A.Stretch( new A.FillRectangle())), new PIC.ShapeProperties( new A.Transform2D( new A.Offset() { X = 0L, Y = 0L }, new A.Extents() { Cx = 990000L, Cy = 792000L }), new A.PresetGeometry( new A.AdjustValueList() ) { Preset = A.ShapeTypeValues.Rectangle })) ) { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" }) ) { DistanceFromTop = (UInt32Value)0U, DistanceFromBottom = (UInt32Value)0U, DistanceFromLeft = (UInt32Value)0U, DistanceFromRight = (UInt32Value)0U, EditId = "50D07946" }); // Append the reference to body, the element should be in a Run. wordDoc.MainDocumentPart.Document.Body.AppendChild(new Paragraph(new Run(element))); } }
Published in
OpenXML
Wednesday, 13 January 2016 07:54
How to Insert a comment into a word processing document
class Program { static void Main(string[] args) { AddCommentOnFirstParagraph("Word8.docx","Open", "test", "This is my comment."); } // Insert a comment on the first paragraph. public static void AddCommentOnFirstParagraph(string fileName, string author, string initials, string comment) { // Use the file name and path passed in as an // argument to open an existing Wordprocessing document. using (WordprocessingDocument document =WordprocessingDocument.Open(fileName, true)) { // Locate the first paragraph in the document. Paragraph firstParagraph = document.MainDocumentPart.Document.Descendants().First(); Comments comments = null; string id = "0"; // Verify that the document contains a // WordProcessingCommentsPart part; if not, add a new one. if (document.MainDocumentPart.GetPartsCountOfType() > 0) { comments = document.MainDocumentPart.WordprocessingCommentsPart.Comments; if (comments.HasChildren) { // Obtain an unused ID. id = comments.Descendants().Select(e => e.Id.Value).Max(); } } else { // No WordprocessingCommentsPart part exists, so add one to the package. WordprocessingCommentsPart commentPart = document.MainDocumentPart.AddNewPart(); commentPart.Comments = new Comments(); comments = commentPart.Comments; } // Compose a new Comment and add it to the Comments part. Paragraph p = new Paragraph(new Run(new Text(comment))); Comment cmt = new Comment() { Id = id, Author = author, Initials = initials, Date = DateTime.Now }; cmt.AppendChild(p); comments.AppendChild(cmt); comments.Save(); // Specify the text range for the Comment. // Insert the new CommentRangeStart before the first run of paragraph. firstParagraph.InsertBefore(new CommentRangeStart() { Id = id }, firstParagraph.GetFirstChild()); // Insert the new CommentRangeEnd after last run of paragraph. var cmtEnd = firstParagraph.InsertAfter(new CommentRangeEnd() { Id = id }, firstParagraph.Elements().Last()); // Compose a run with CommentReference and insert it. firstParagraph.InsertAfter(new Run(new CommentReference() { Id = id }), cmtEnd); } } }
Published in
OpenXML
Wednesday, 13 January 2016 07:53
How to Delete comments by all or a specific author
class Program { static void Main(string[] args) { DeleteComments("DeleteComments.docx","Gary zhang"); } public static void DeleteComments(string fileName, string author = "") { // Get an existing Wordprocessing document. using (WordprocessingDocument document = WordprocessingDocument.Open(fileName, true)) { // Set commentPart to the document WordprocessingCommentsPart, // if it exists. WordprocessingCommentsPart commentPart = document.MainDocumentPart.WordprocessingCommentsPart; // If no WordprocessingCommentsPart exists, there can be no // comments. Stop execution and return from the method. if (commentPart == null) { return; } // Create a list of comments by the specified author, or // if the author name is empty, all authors. List commentsToDelete = commentPart.Comments.Elements().ToList(); if (!String.IsNullOrEmpty(author)) { commentsToDelete = commentsToDelete. Where(c => c.Author == author).ToList(); } IEnumerable commentIds = commentsToDelete.Select(r => r.Id.Value); // Delete each comment in commentToDelete from the // Comments collection. foreach (Comment c in commentsToDelete) { c.Remove(); } // Save the comment part change. commentPart.Comments.Save(); Document doc = document.MainDocumentPart.Document; // Delete CommentRangeStart for each // deleted comment in the main document. List commentRangeStartToDelete = doc.Descendants(). Where(c => commentIds.Contains(c.Id.Value)).ToList(); foreach (CommentRangeStart c in commentRangeStartToDelete) { c.Remove(); } // Delete CommentRangeEnd for each deleted comment in the main document. List commentRangeEndToDelete = doc.Descendants(). Where(c => commentIds.Contains(c.Id.Value)).ToList(); foreach (CommentRangeEnd c in commentRangeEndToDelete) { c.Remove(); } // Delete CommentReference for each deleted comment in the main document. List commentRangeReferenceToDelete = doc.Descendants(). Where(c => commentIds.Contains(c.Id.Value)).ToList(); foreach (CommentReference c in commentRangeReferenceToDelete) { c.Remove(); } // Save changes back to the MainDocumentPart part. doc.Save(); } } }
Published in
OpenXML
Wednesday, 13 January 2016 07:50
How to Convert a word processing document from the DOCM to the DOCX file format
class Program { static void Main(string[] args) { string filename = "WithMacros.docm"; ConvertDOCMtoDOCX(filename); } // Given a .docm file (with macro storage), remove the VBA // project, reset the document type, and save the document with a new name. public static void ConvertDOCMtoDOCX(string fileName) { bool fileChanged = false; using (WordprocessingDocument document = WordprocessingDocument.Open(fileName, true)) { // Access the main document part. var docPart = document.MainDocumentPart; // Look for the vbaProject part. If it is there, delete it. var vbaPart = docPart.VbaProjectPart; if (vbaPart != null) { // Delete the vbaProject part and then save the document. docPart.DeletePart(vbaPart); docPart.Document.Save(); // Change the document type to // not macro-enabled. document.ChangeDocumentType( WordprocessingDocumentType.Document); // Track that the document has been changed. fileChanged = true; } } // If anything goes wrong in this file handling, // the code will raise an exception back to the caller. if (fileChanged) { // Create the new .docx filename. var newFileName = Path.ChangeExtension(fileName, ".docx"); // If it already exists, it will be deleted! if (File.Exists(newFileName)) { File.Delete(newFileName); } // Rename the file. File.Move(fileName, newFileName); } } }
Published in
OpenXML
Wednesday, 13 January 2016 07:49
How to Add tables to word processing documents
class Program { static void Main(string[] args) { string fileName = "Word10.docx"; CreateTable(fileName); } // Insert a table into a word processing document. public static void CreateTable(string fileName) { using (WordprocessingDocument doc = WordprocessingDocument.Create(fileName, WordprocessingDocumentType.Document)) { MainDocumentPart mainPart = doc.AddMainDocumentPart(); mainPart.Document = new Document(); Body body = mainPart.Document.AppendChild(new Body()); Table tb = new Table(); TableRow row = new TableRow(); TableCell cel = new TableCell(new Paragraph(new Run(new Text("OpenXML")))); row.AppendChild(cel); tb.AppendChild(row); body.Append(tb); } }
Published in
OpenXML
Wednesday, 13 January 2016 07:46
How to Accept all revisions in a word processing document
class Program { static void Main(string[] args) { string docName = "OpenXML.docx"; string authorName = "Gary zhang"; AcceptRevisions(docName, authorName); } public static void AcceptRevisions(string fileName, string authorName) { // Given a document name and an author name, accept revisions. using (WordprocessingDocument wdDoc = WordprocessingDocument.Open(fileName, true)) { Body body = wdDoc.MainDocumentPart.Document.Body; // Handle the formatting changes. List changes = body.Descendants() .Where(c => c.Author.Value == authorName).Cast().ToList(); foreach (OpenXmlElement change in changes) { change.Remove(); } // Handle the deletions. List deletions = body.Descendants() .Where(c => c.Author.Value == authorName).Cast().ToList(); deletions.AddRange(body.Descendants() .Where(c => c.Author.Value == authorName).Cast().ToList()); deletions.AddRange(body.Descendants() .Where(c => c.Author.Value == authorName).Cast().ToList()); foreach (OpenXmlElement deletion in deletions) { deletion.Remove(); } // Handle the insertions. List insertions = body.Descendants() .Where(c => c.Author.Value == authorName).Cast().ToList(); insertions.AddRange(body.Descendants() .Where(c => c.Author.Value == authorName).Cast().ToList()); insertions.AddRange(body.Descendants() .Where(c => c.Author.Value == authorName).Cast().ToList()); foreach (OpenXmlElement insertion in insertions) { // Found new content. // Promote them to the same level as node, and then delete the node. foreach (var run in insertion.Elements()) { if (run == insertion.FirstChild) { insertion.InsertAfterSelf(new Run(run.OuterXml)); } else { insertion.NextSibling().InsertAfterSelf(new Run(run.OuterXml)); } } insertion.RemoveAttribute("rsidR", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); insertion.RemoveAttribute("rsidRPr", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); insertion.Remove(); } } } }
Published in
OpenXML
Wednesday, 13 January 2016 06:55
Create a word processing document
class Program { static void Main(string[] args) { CreateWordprocessingDocument("Create a word processing document.doc"); } public static void CreateWordprocessingDocument(string filepath) { // Create a document by supplying the filepath. using (WordprocessingDocument wordDocument = WordprocessingDocument.Create(filepath, WordprocessingDocumentType.Document)) { // Add a main document part. MainDocumentPart mainPart = wordDocument.AddMainDocumentPart(); // Create the document structure and add some text. mainPart.Document = new Document(); Body body = mainPart.Document.AppendChild(new Body()); Paragraph para = body.AppendChild(new Paragraph()); Run run = para.AppendChild(new Run()); run.AppendChild(new Text("Create text in body - CreateWordprocessingDocument")); } } }
Published in
OpenXML