How to add hyperlinks into Word docx using open XML? - c#

I am having a trouble adding hyperlinks to my word document. I don't know how to do it. I would like to make a link in a word document from my C# code using open xml. Is ther a different solution using only href or sth similar? There is a HyperLink class on the net from Open XML but how to use it?

Try this
using (WordprocessingDocument doc = WordprocessingDocument.Open("", true))
{
doc.MainDocumentPart.Document.Body.AppendChild(
new Paragraph(
new Hyperlink(new Run(new Text("Click here")))
{
Anchor = "Description",
DocLocation = "location",
}
)
);
doc.MainDocumentPart.Document.Save();
}

Related

add html content in existing docx file using openxml in C#

How do I add/append HTML content in an existing .docx file, using OpenXML in asp.net C#?
In an existing word file, I want to append the html content part.
For example:
In this example, I want to place "This is a Heading" inside a H1 tag.
Here its my code
protected void Button1_Click(object sender, EventArgs e)
{
try
{
using (WordprocessingDocument doc = WordprocessingDocument.Open(#"C:\Users\admin\Downloads\WordGenerator\WordGenerator\FTANJS.docx", true))
{
string altChunkId = "myId";
MainDocumentPart mainDocPart = doc.MainDocumentPart;
var run = new Run(new Text("test"));
var p = new Paragraph(new ParagraphProperties(new Justification() { Val = JustificationValues.Center }), run);
var body = mainDocPart.Document.Body;
body.Append(p);
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes("<html><head></head><body><h1>HELLO</h1></body></html>"));
// Uncomment the following line to create an invalid word document.
// MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes("<h1>HELLO</h1>"));
// Create alternative format import part.
AlternativeFormatImportPart formatImportPart =
mainDocPart.AddAlternativeFormatImportPart(
AlternativeFormatImportPartType.Html, altChunkId);
//ms.Seek(0, SeekOrigin.Begin);
// Feed HTML data into format import part (chunk).
formatImportPart.FeedData(ms);
AltChunk altChunk = new AltChunk();
altChunk.Id = altChunkId;
mainDocPart.Document.Body.Append(altChunk);
}
}
catch (Exception ex)
{
ex.ToString ();
}
}
Add HTML content as Chunk should work, and you are almost there.
If I understand the question properly, this code should work.
//insert html content to H1 tag
using(WordprocessingDocument fDocx = WordprocessingDocument.Open(sDocxFile,true))
{
string sChunkID = "myhtmlID";
AlternativeFormatImportPart oChunk = fDocx.MainDocumentPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.Html, sChunkID);
using(FileStream fs = File.Open(sHtml,FileMode.OpenOrCreate))
{
oChunk.FeedData(fs);
}
AltChunk oAltChunk = new AltChunk();
oAltChunk.Id =sChunkID ;
//insert html to the tag of 'H1' and remove H1.
Body body = fDocx.MainDocumentPart.Document.Body;
Paragraph theParagraph = body.Descendants<Paragraph>().Where(p => p.InnerText == "H1").FirstOrDefault();
theParagraph.InsertAfterSelf<AltChunk>(oAltChunk);
theParagraph.Remove();
fDocx.MainDocumentPart.Document.Save();
}
The short answer is "You can't add HTML to a docx file".
Docx is an open format defined here. If you're using the Microsoft version they have a number of extensions.
In any case, the file contains XML, not HTML and you can't simply add HTML to a docx file. There are styles and formatting objects and pointers that all need to be updated.
If you need to modify a docx file and don't want to do a lot of research and a lot of coding, you'll need to find an existing library to work with.

Loading an online image in a word document

Im developing a wpf app that simply inserts an image to a word document. Each time the word document is open i want the picture to call the image from a server, for example (server.com/Images/image_to_be_insert.png)
My code is as follow:
Application application = new Application();
Document doc = application.Documents.Open(file);
var img = doc.Application.Selection.InlineShapes.AddPicture("server.com/Images/img.png");
img.Height = 20;
img.Width = 20;
document.Save();
document.Close();
Basically what my code does is, download the image then add it to the document. What i want to do is that i want the image to be loaded from the server whenever the word document is opened.
Instead of using the Office Interop libraries, you could achieve this using the new OpenXML SDK which does not require MS Office to be installed in order to work.
Requirements
Install the OpenXML NuGet from Visual Studio: DocumentFormat.OpenXml
Add the required namespaces:
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Vml;
using DocumentFormat.OpenXml.Wordprocessing;
The code
using (WordprocessingDocument package = WordprocessingDocument.Create(#"c:/temp/img.docx", WordprocessingDocumentType.Document))
{
package.AddMainDocumentPart();
var picture = new Picture();
var shape = new Shape() { Style="width: 272px; height: 92px" };
var imageData = new ImageData() { RelationshipId = "rId1" };
shape.Append(imageData);
picture.Append(shape);
package.MainDocumentPart.Document = new Document(
new Body(
new Paragraph(
new Run(picture))));
package.MainDocumentPart.AddExternalRelationship("http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
new System.Uri("https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png", System.UriKind.Absolute), "rId1");
package.MainDocumentPart.Document.Save();
}
This will create a new Word document that will load the Google logo from the provided URL when open it.
References
https://msdn.microsoft.com/en-us/library/dd440953(v=office.12).aspx
How can I add an external image to a word document using OpenXml?

create Hyperlink with docx.dll?

How to create hyperlink with docx.dll dynamically , currently tried below but not working
using (DocX document = DocX.Create(#"Test.docx"))
{
// Add a hyperlink to this document.
Hyperlink h = document.AddHyperlink
("Google", new Uri("http://www.google.com"));
// Add a new Paragraph to this document.
Paragraph p = document.InsertParagraph();
p.Append("My favourite search engine is ");
p.AppendHyperlink(h);
p.Append(", I think it's great.");
// Save all changes made to this document.
document.Save();
}
How about using p.AppendHyperlink("www.google.com", "Google", HyperlinkType.WebLink);
?
Additionally , you can take a reference from Insert Hyperlink to Word in C# .

FeedData into a FooterPart

I've created a word document docx and am now in the process of "reverse engineering" it with the OpenXml productivity tool. I'm using .FeedData() to feed the styles, theme etc. into the document, which I'm saving as .xml files from the reflection - and all was going well, until I came to the footer.
Here's what I'm doing for the styles (this works perfectly fine):
StyleDefinitionsPart styleDefinitionsPart = mainPart.AddNewPart<StyleDefinitionsPart>();
using (FileStream fs = new FileStream(Server.MapPath("styles.xml"), FileMode.Open, FileAccess.Read))
{
styleDefinitionsPart.FeedData(fs);
}
Looking at my document, everything is there - now I reflect on the footer part, save the xml to footer.xml and add the part like this:
FooterPart footerPart = mainPart.AddNewPart<FooterPart>();
using (FileStream fs = new FileStream(Server.MapPath("footer.xml"), FileMode.Open, FileAccess.Read))
{
footerPart.FeedData(fs);
}
Everything else looks fine, I can see the part in my document, but the footer just isn't appearing ON the document, what am I doing wrong here? Do I need to tell the document which footer part to use or something?
Fixed. It seems there has to be some content in the body before you can add a footer and header to it, then you need to add a reference to them for each section like this:
foreach (var section in mainPart.Document.Body.Elements<WP.SectionProperties>())
{
section.PrependChild<WP.HeaderReference>(new WP.HeaderReference() { Id = mainPart.GetIdOfPart(headerPart) });
section.PrependChild<WP.FooterReference>(new WP.FooterReference() { Id = mainPart.GetIdOfPart(footerPart) });
}
Remember to add your header and footer last, so there is content in the document.
HUGE thanks to this answer: Add Header and Footer to an existing empty word document with OpenXML SDK 2.0

Server-side word automation

I am looking for alternatives to using openxml for a server-side word automation project. Does anyone know any other ways that have features to let me manipulate word bookmarks and tables?
I am currently doing a project of developing a word automation project for my company and I am using DocX Very simple and straight forward API to work with. The approach I am using is, whenever I need to work with XML directly, this API has a property named "xml" in the Paragraph class which gives you access to the underlying xml direclty so that I can work with it. The best part is its not breaking the xml and not corrupting the resulting document. Hope this helps!
Example code using DocX..
XNamespace ns = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
using(DocX doc = DocX.Load(#"c:\temp\yourdoc.docx"))
{
foreach( Paragraph para in doc.Paragraphs )
{
if(para.Xml.ToString().Contains("w:Bookmark"))
{
if(para.Xml.Element(ns + "BookmarkStart").Attribute("Name").Value == "yourbookmarkname")
{
// you got to your bookmark, if you want to change the text..then
para.Xml.Elements(ns + "t").FirstOrDefault().SetValue("Text to replace..");
}
}
}
}
Alternative API exclusively to work with bookmarks is .. http://simpleooxml.codeplex.com/
Example on how to delete text from bookmarkstart to bookmarkend using this API..
MemoryStream stream = DocumentReader.Copy(string.Format("{0}\\template.docx", TestContext.TestDeploymentDir));
WordprocessingDocument doc = WordprocessingDocument.Open(stream, true);
MainDocumentPart mainPart = doc.MainDocumentPart;
DocumentWriter writer = new DocumentWriter(mainPart);
//Simply Clears all text between bookmarkstart and end
writer.PasteText("", "YourBookMarkName");
//Save to the memory stream, and then to a file
writer.Save();
DocumentWriter.StreamToFile(string.Format("{0}\\templatetest.docx", GetOutputFolder()), stream);
Loading the word document into different API's from memory stream.
//Loading a document file into memorystream using SimpleOOXML API
MemoryStream stream = DocumentReader.Copy(#"c\template.docx");
//Opening it from the memory stream as OpenXML document
WordprocessingDocument doc = WordprocessingDocument.Open(stream, true);
//Opening it as DocX document for working with DocX Api
DocX document = DocX.Load(stream);

Categories

Resources