How to insert hyperlink in powerpoint slide using Open XML? - c#

I have a scenario where I have to replace the certain variables from slide template with tabular data but in this case data and slide text is overlapping and after some research I found out that PowerPoint is not designed for such cases [MS Link] (img 1). To overcome this I though instead of replacing the variables with tabular data, I should replace the variable with the link which will point the newly created slide where I can post my tabular data (img 2).
So come back to my question, Is there any way I can write the data without messing the template? OR How can I replace the variable with the hyperlink to the slide?

According to the Documentation you can do something like this, just adjust to your case and how to find the variable1.
// Open the presentation file as read-only.
using (PresentationDocument document = PresentationDocument.Open(fileName, false))
{
// Iterate through all the slide parts in the presentation part.
foreach (SlidePart slidePart in document.PresentationPart.SlideParts)
{
IEnumerable<Drawing.HyperlinkType> links = slidePart.Slide.Descendants<Drawing.HyperlinkType>();
// Iterate through all the links in the slide part.
foreach (Drawing.HyperlinkType link in links)
{
// Iterate through all the external relationships in the slide part.
foreach (HyperlinkRelationship relation in slidePart.HyperlinkRelationships)
{
// If the relationship ID matches the link ID…
if (relation.Id.Equals(link.Id))
{
// Add the URI of the external relationship to the list of strings.
ret.Add(relation.Uri.AbsoluteUri);
}
}
}
}
}

Related

How to programmatically copy content(Paragraphs,Tables,etc.) in order from a Word document using Office.Interop.Word?

I need to import a Word document by parts and store in a DB. The following code works well with paragraphs, but other items like Tables, images are missing.
foreach (Word.Paragraph item in this.oDoc.Paragraphs)
{
r = item.Range;
r.Copy();
SaveInDB();
}
I need to keep the document order of paragraphs,tables,etc. as they appear so I cannot process each separately unless there were some way to check the order of each item.

Any way to get the position of an AcroField in PdfSharp without "/Rect"?

I am developing a program with C# and the library PDFSharp.
I am currently using the following code to get the X and Y coordinates of a specific AcroField in a PDF document:
PdfTextField imageField = (PdfTextField)inForm.Fields[elementName];
PdfRectangle rect = imageField.Elements.GetRectangle(PdfAnnotation.Keys.Rect);
This works fine if there is only 1 Field with the same name present in the PDF Document. However, if there are two fields both named "FirstName", even if they are on separate pages, this seems to remove the "/Rect" and "/P" flags, so I cannot use these to find the position or the page relevant to that field.
Is there any other way to get the position of a Field in the PDF, or any way to activate the "/Rect" and "/P" flags?
Thanks, RBrNx
What Mihai posted fits what I discovered from reverse engineering the PDF via PdfSharp. If there are multiple fields in the same document, they are nested under a parent container, and it is a reference to this parent container which PdfSharp will give you when using the AcroForm.Fields accessor. To get the Page and Rectangle elements for each field, you have to look at the children of that container.
To get the values you are looking for, you'll want to do something like this:
PdfTextField imageField = (PdfTextField)inForm.Fields[elementName];
var fieldRectangles = new List<PdfRectangle>();
if( imageField.HasKids )
{
PdfArray kids = (PdfArray) Elements[Keys.Kids];
foreach( var kid in kids )
{
var kidValues = ((PdfReference) kid).Value as PdfDictionary;
var rectangle = kidValues.Elements.GetRectangle(PdfAnnotation.Keys.Rect);
fieldRectangles.Add(rectangle);
}
}
The page reference element ("/P" tag) is also available from these "Kid" elements.
I'm not familiar with PDFSharp API but this is how it works in PDF:
- form fields have document scope and not page scope.
- 2 or more fields with the same name are in fact a single field with 2 or more widgets (widget annotations, the visual representation of a field). The /Rect and /P entries are stored at widget level. When the field has one widget, the widget is merged with the field so the /Rect and /P entries appear to be part of the field.
In your scenario you have to look for the /Kids key which is an array. Drill down through the /Kids array (a child can have his own kids and so on) till the last level where the /Kids is no longer present. At this level you should find the /Rect and /P keys.
Each widget can have its own /Rect and /P keys since they can appear on different pages at different positions.

Add dynamic table row using microsoft work automation c#

I have a word document template which contains several form fields that need to be filled using c# code.
below is the document image
The code below is used to reach and fill the document form fields,
But when i reach the table sections sometimes the rows need to be filled are more than what is pre defined inside the template.
red marked area is the table which i want to fill it with data and create as many rows as needed.
the code i use for filling the data is
string fileName = Path.GetTempFileName();
File.WriteAllBytes(fileName, Properties.Resources.DocumentTemplate);
Word.Application word = new Word.Application();
Word.Document doc = new Word.Document();
doc = word.Documents.Add(fileName);
doc.Activate();
doc.FormFields["file_num"].Range.Text = "some text";
doc.FormFields["fam_size"].Range.Text = "another text";
doc.FormFields["nationality"].Range.Text = "another text";
for(int i =0; i< rowsInDatabaseCount; i++)
{
//i don't know how to add row and reach each form field inside
}
I hope someone can help me on how to achieve what i want.
Thank you in advance...
There are multiple ways to handle that.
1) Since the data is coming from a database, one way is to use InsertDatabase method.
2) You could insert the block as tab or comma separated text then convert to a table using ConvertToTable() method.
3) You might use Rows and Cols collections (of Table) and .Add method to add new rows.
4) You might instead create your template as an XSL and transform data (XML) using that XSL to generate final HTM. Word is able to open an HTM file.
(All these options worked for me in "resume", "test results" ... creations which have similar layouts to the ones you gave. I found final option 4 to be the most dynamic one, where end users could define their own templates using simple HTML editors - worked better than word templates for me).

Create repeating blocks in word document using c#

Hello I am automating a word document from a winforms application using c#. The document contains a number of mail merge fields that I fill from my code. This works fine for fixed fields.
However the document contains a few recurring sections that are repeated n times at run time. Can someone tell me how to create a block of some sort that can be inserted multiple times?
I have tried inserting the text between two bookmarks however this messes up the page formatting.
Any advice would be much appreciated.
Edit:
The function below is what I use to merge the data on to the word template. The Dictionary holds the field name in the first string and the content in the second.
The user is given a sample word template with all the field codes in the document and is then able to change the order of the fields and the styling on his own.
public static void CreateBody(Application wApp, Document wDoc, Dictionary<string, string> fieldContent)
{
//Loop through fields in document body.
foreach (Field mergeField in wDoc.Fields)
{
//Find mailmerge fields in the Word document body.
if (mergeField.Type == WdFieldType.wdFieldMergeField)
{
//Get the fieldName from the template file.
string fieldText = mergeField.Code.Text;
string fieldName = GetFieldName(fieldText);
if (fieldContent.ContainsKey(fieldName))
{
mergeField.Select();
if (fieldContent[fieldName] != "")
{
wApp.Selection.TypeText(fieldContent[fieldName]);
}
else
{
//If the field has no content remove the field text from the word file.
wApp.Selection.TypeText(" ");
}
}
}
}
Now I am looking for a way to repeat a block of mail merge fields in the template and have them be inserted multiple times, once for each record.
Here is MSDN link which help you to resolve your issue.
Building a Word Document Using SQL Server Data

Extracting data stored tables in .docx file with C#

When I run the following code on a .docx file the child2.innerText will print out the information I am after (although without seperating text from the seperate columns of the table).
My problem is that the associated innerXml is completely incomprehensible for me. I thought that there would be an 'get cell from table' method or such. I have literally no idea how to extract columns/rows from the xml I've been given though.
I'm completely new to C#, so I might be missing something obvious.
I am using the openxml and the file is .docx.
using (WordprocessingDocument wdoc = WordprocessingDocument.Open(pathToMiniToktrapport, false))
{
var table = wdoc.MainDocumentPart.Document.Body.Elements<Table>();
foreach (var child in table)
{
foreach (var child2 in child) {
System.Console.WriteLine(child2.InnerXml);
System.Console.WriteLine(child2.InnerText);
System.Console.ReadLine();
}
}
}
Thanks!
Please go through the link in MSDN which shows the typical structure and sample code
http://msdn.microsoft.com/en-us/library/office/cc850835.aspx

Categories