Link to another file - c#

I'm generating a word document by using open-xml.
There i show names of image files
i.e.
c:\config\1.jpg
c:\config\2.jpg
On-click on those names (cntl+click) those file should be opened. But it doesnt go to the file rather than an anchor to top of the word doc.
I used hyperlink as below
Paragraph paraSummary = body.AppendChild(new Paragraph());
Run runSummary = paraSummary.AppendChild(new Run());
runSummary.AppendChild(new Break());
Hyperlink hl = new Hyperlink(new Run(new Text(item.ToString())))
{
DocLocation = rootPath1 + "\\" + item.ToString()
};
runSummary.AppendChild(hl);
mainPart.Document.Append(body);
mainPart.Document.Save();
and the xml of generated file is :
-<w:hyperlink w:docLocation="c:\\config\\1.jpg">-<w:r><w:t>1.jpg</w:t></w:r></w:hyperlink>
is there any other solution other than 'Hyperlinks' or anything that i have missed in above code.

According to the Open XML spec.
http://officeopenxml.com/WPhyperlink.php
docLocation is for external links.
For All types of hyperlinks we have to create a relationship.
for example
In your case TargetMode can't be external
In Open XML SDK you can implement this as below code sample
Hyperlink hl =
new Hyperlink(new Run(new Text("Link1")))
{
Id = "L1"
};
runSummary.AppendChild(hl);
mainPart.Document.Append(body);
mainPart.AddHyperlinkRelationship(new Uri("file:\\C:\\config\\image.jpg"), false, "L1");
in AddHyperlinkRelationship method false means that this is not external link (which is for internal link)

Related

Add a new paragraph in Word which includes DOCPROPERTY fields using OpenXML in C#

I'm writing a application that can edit paragraphs in a Word Template (.docx). In these paragraphs they can contain custom DOCPROPERTY. I can read and edit the paragraph then write them back successfully, however when I write them back when a DOCPROPERTY is included it writes it back as text.
An example of my code to edit a paragraph is as follows. I understand why this is happening in my code because I'm writing it as Text. my question is how I write DOCPROPERTY to a .docx file so Word reads it as DOCPROPERTY and not text.
paragraph.RemoveAllChildren<Run>();
paragraph.AppendChild<Run>(new Run(new Text("DOCPROPERTY "System" \* MERGEFORMAT")));
I've searched around and cannot see a suitable example.
I've found how to do it.
Run r = new Run();
Text t = new Text();
t.Text = "System";
r.Append(t);
r.Append(new Text { Text = " ", Space = SpaceProcessingModeValues.Preserve });
r.Append(new SimpleField() { Instruction = #"DOCPROPERTY System \\*MERGEFORMAT" });
paragraph.Append(r);

Remaining Space on PDF Page

I am currently designing a report for a customer and I have to place a text at the bottom of the last page. I have to do it while generating each quarter for 16k pdfs.
iText 7.1.5 is used, but will be upgraded to the latest version with the next release.
Doing it with a Footer on every page is not an option because the paragraph can have up to 14 lines of text. Adding a normal paragraph at the end of the document is also no solution because my client requested that the text is on top of the footer.
The expected result:
current generation of PDFs
PdfADocument pdf = new PdfADocument(...)
...
// handler for adding header and footer on every page
pdf.AddEventHandler(PdfDocumentEvent.END_PAGE, headerFooterHandler);
Document doc = new Document(pdf);
doc.SetTopMargin(ConversionUtility.MillimeterToPoint(48));
doc.SetLeftMargin(ConversionUtility.MillimeterToPoint(26));
doc.SetRightMargin(ConversionUtility.MillimeterToPoint(18));
doc.SetBottomMargin(ConversionUtility.MillimeterToPoint(26));
... Some customer specific code
// paragraphs and data table is added
foreach(var feeLine in feeList.Values) {
switch (feeLine.Type) {
case "U":
case "T1":
case "T2":
case "BS":
doc.Add(GenerateTextBlock(feeLine, CheckSameType(feeLine.Type, feeList, i)));
break;
case "U3":
doc.Add(GenerateTextBlock(feeLine, CheckSameType(feeLine.Type, feeList, i)));
GenerateTableBlockStart(GetColumnCount(feeList[i + 1]));
break;
default:
if (CheckEndOfTable(feeList, i)) {
var table = GenerateTableBlock(feeLine, ColumnCount, true);
doc.Add(table);
table.Complete();
} else {
GenerateTableBlock(feeLine, ColumnCount, false);
}
break;
}
}
headerFooterHandler.WritePageTotal(pdf);
doc.Close();
I would need some advise / piece of code how to find the remaining space on the last page. Placing and writing the text is no problem.
You can use the absolute positioning to position the text right where you want for the last page. All you need to know is to find the position where you want to place the paragraph. This can be done by opening any pdf in a PDF Reader such as Adobe / Foxit Reader and changing the ruler to points. Now all you need is to zoom in and find the position where you want to place the text. For example
`string dest = "destination pdf's path"
//Initialize PDF Writer
writer = new PdfWriter(dest);
//Initialize PDF Document
pdf = new PdfDocument(writer);
// Initialize document
document = new Document(pdf, PageSize.A4);
//You page text here
Paragraph p = new Paragraph("bla bla bla bla ");
document.Add(p);
//Write what ever you want to write on the page...
.
.
Paragraph footer = new Paragraph("some text")
footer.SetFixedPosition(72f, 50f, 500f);
footer.SetFontSize(6f);
document.Add(footer);
document.Close();`
As you fill the main page area only using a Document with a default DocumentRenderer, you can simply query the current area of the document renderer.
E.g. this piece of code writes into each line the bounding box of available space before drawing the line in question:
using (PdfWriter pdfWriter = new PdfWriter(#"DetermineRemainingSpace.pdf"))
using (PdfDocument pdfDocument = new PdfDocument(pdfWriter))
using (Document document = new Document(pdfDocument))
{
for (int i = 0; i < 30; i++)
{
Rectangle currentBox = document.GetRenderer().GetCurrentArea().GetBBox();
string current = string.Format(CultureInfo.InvariantCulture, "{0:F}×{1:F} from ({2:F}, {3:F}) to ({4:F}, {5:F})", currentBox.GetWidth(), currentBox.GetHeight(),
currentBox.GetLeft(), currentBox.GetBottom(), currentBox.GetRight(), currentBox.GetTop());
document.Add(new Paragraph(string.Format("{0:D2}, previously available {1}", i, current)));
}
}
The output:
Thus,
I would need some advise / piece of code how to find the remaining space on the last page. Placing and writing the text is no problem.
simply query the document renderer current area as above after all regular content has been added to the document.

How to dynamically link bookmarks to table of contents using PDFsharp + MigraDoc

I'm trying to create a Table of Contents using MigraDoc and PDFsharp and I've gotten really close but the problem I'm currently having is that the links on the Table of Contents all take me to the very first page of the PDF. I'm trying to link them to their respective pages. PDFSharp bookmarks work fine but when trying to create a table of contents based on the merged PDF it's not working.
static void TableOfContents(PdfDocument document)
{
// Puts the Table of contents on the second page
PdfPage page = document.Pages[1];
XGraphics gfx = XGraphics.FromPdfPage(page);
gfx.MUH = PdfFontEncoding.Unicode;
// Create MigraDoc document + Setup styles
Document doc = new Document();
Styles.DefineStyles(doc);
// Add header
Section section = doc.AddSection();
Paragraph paragraph = section.AddParagraph("Table of Contents");
paragraph.Format.Font.Size = 14;
paragraph.Format.Font.Bold = true;
paragraph.Format.SpaceAfter = 24;
paragraph.Format.OutlineLevel = OutlineLevel.Level1;
// Add links - these are the PdfSharp outlines/bookmarks
// added previously when concatinating the pages
foreach (var bookmark in document.Outlines)
{
paragraph = section.AddParagraph();
paragraph.Style = "TOC";
paragraph.AddBookmark(bookmark.Title);
Hyperlink hyperlink = paragraph.AddHyperlink(bookmark.Title);
hyperlink.AddText($"{bookmark.Title}\t");
hyperlink.AddPageRefField(bookmark.Title);
}
// Render document
DocumentRenderer docRenderer = new DocumentRenderer(doc);
docRenderer.PrepareDocument();
docRenderer.RenderPage(gfx, 1);
gfx.Dispose();
}
Ideally I want it to return the file's name (which it's doing) and the page number (it's only returning the first page). This is what it's currently outputting.
Table of Contents
file name here......................... 1
file name here......................... 1
file name here......................... 1
file name here......................... 1
As I understand it, the Hyperlink and bookmark should be unique to the document.
Otherwise the link will be made to the first paragraph containing the bookmark.
I simply use a number which I increase for a simple report I make.
private void DefineTOCLine(int level, string text, Paragraph linkTo)
{
var tocIndex = (tocindex++).ToString(CultureInfo.InvariantCulture);
var paragraph = tocsection.AddParagraph();
paragraph.Style = level == 1 ? "TOC1" : "TOC2";
var hyperlink = paragraph.AddHyperlink(tocIndex);
hyperlink.AddText(text + "\t");
hyperlink.AddPageRefField(tocIndex);
linkTo.AddBookmark(tocIndex);
}
You invoke hyperlink.AddPageRefField to set a reference, but as far as I can tell you never create the MigraDoc bookmark for the target of the reference by calling MigraDoc's AddBookmark method.
MigraDoc bookmarks are different from PDF file bookmarks.

C# word document

I want to read a word document without opening it. Then replace some text in it and then save it with another name in the same format using C#. But the document is not being saved with the changes but int the same way as the original document. Any help will be appreciated. Thanks in advance.
string path = Server.MapPath("~/CustomerDocument/SampleNDA5.docx");
WordprocessingDocument wordprocessingDocument = WordprocessingDocument.Open(path, false);
{
var body = wordprocessingDocument.MainDocumentPart.Document.Body;
foreach (var text in body.Descendants<Text>())
{
if (text.Text.Contains("<var_Date>"))
{
text.Text = text.Text.Replace("<var_Date>", DateTime.Now.ToString("MMM dd,yyyy"));
}
}
wordprocessingDocument.SaveAs(Server.MapPath("~/CustomerDocument/SampleNDA10.docx"));
wordprocessingDocument.Close();
}
I think this should help. It explains how to put edits back into a collection.
https://www.codeproject.com/Articles/87616/List-T-ForEach-or-Foreach-It-Doesn-t-Matter-Or-Doe
So if your word template is the same each time you essentially
Copy The Template
Work On The Template
Save In Desired Format
Delete Template Copy
Each of the sections that you are replacing within your word document you have to insert a bookmark for that location (easiest way to input text in an area).
I always create a function to accomplish this, and I end up passing in the path - as well as all of the text to replace my in-document bookmarks. The function call can get long sometimes, but it works for me.
Application app = new Application();
Document doc = app.Documents.Open("sDocumentCopyPath.docx");
if (doc.Bookmarks.Exists("bookmark_1"))
{
object oBookMark = "bookmark_1";
doc.Bookmarks.get_Item(ref oBookMark).Range.Text =
"My Text To Replace bookmark_1";
}
if (doc.Bookmarks.Exists("bookmark_2"))
{
object oBookMark = "bookmark_2";
doc.Bookmarks.get_Item(ref oBookMark).Range.Text =
"My Text To Replace bookmark_2";
}
doc.ExportAsFixedFormat("myNewPdf.pdf", WdExportFormat.wdExportFormatPDF);
((_Document)doc).Close();
((_Application)app).Quit();
This code should get you up and running unless you want to pass in all the values into a function.
If you need some more explanation I can help as well :) my example saves it as a .pdf, but you can do any format you prefer.

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# .

Categories

Resources