In my ASP.net program i have a class to open a word document, find a boormark and insert a given text
The error i get is: the name SpaceProcessingModeValues does not exist in the current context.
using (WordprocessingDocument document = WordprocessingDocument.Open(strFileName, true))
{
MainDocumentPart mainPart = document.MainDocumentPart;
IEnumerable<BookmarkStart> res = from bm in mainPart.Document.Body.Descendants<BookmarkStart>()
where bm.Name == "strField"
select bm;
int x = 0;
BookmarkStart bookmark = res.SingleOrDefault();
if (bookmark != null)
{
OpenXmlElement parent = bookmark.Parent; // bookmark's parent element
var paragraph1 = new Paragraph {RsidParagraphAddition = "00023529", RsidRunAdditionDefault = "003E1BA6"};
var run1 = new Run();
var text1 = new Text("Text : "){ Space = SpaceProcessingModeValues.Preserve };
run1.Append(text1);
var bookmarkStart1 = new BookmarkStart {Name = "_GoBack", Id = 0};
var bookmarkEnd1 = new BookmarkEnd {Id = 0};
var run2 = new Run();
var text2 = new Text();
text2.Text = strGivenText;
run2.Append(text2);
paragraph1.Append(run1);
paragraph1.Append(bookmarkStart1);
paragraph1.Append(bookmarkEnd1);
paragraph1.Append(run2);
parent.InsertBeforeSelf(paragraph1);
}
// close saves all parts and closes the document
mainPart.Document.Save();
document.Close();
}
You need to add the references DocumentFormat.OpenXml namespace
Related
I want to generate a DocX file with footer from HTML.
Using the following lib: DocumentFormat.OpenXml
I manage to generate the DocX file, BUT without Footer.
The code that I use is the following:
class HtmlToDoc
{
public static byte[] GenerateDocX(string html)
{
MemoryStream ms;
MainDocumentPart mainPart;
Body b;
Document d;
AlternativeFormatImportPart chunk;
AltChunk altChunk;
string altChunkID = "AltChunkId1";
ms = new MemoryStream();
using(var myDoc = WordprocessingDocument.Create(ms, WordprocessingDocumentType.Document))
{
mainPart = myDoc.MainDocumentPart;
if (mainPart == null)
{
mainPart = myDoc.AddMainDocumentPart();
b = new Body();
d = new Document(b);
d.Save(mainPart);
}
chunk = mainPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.Xhtml, altChunkID);
using (Stream chunkStream = chunk.GetStream(FileMode.Create, FileAccess.Write))
{
using (StreamWriter stringStream = new StreamWriter(chunkStream))
{
stringStream.Write("<html><head></head><body>" + html + "</body></html>");
}
}
altChunk = new AltChunk();
altChunk.Id = altChunkID;
mainPart.Document.Body.InsertAt(altChunk, 0);
AddFooter(myDoc);
mainPart.Document.Save();
}
return ms.ToArray();
}
private static void AddFooter(WordprocessingDocument doc)
{
string newFooterText = "New footer via Open XML Format SDK 2.0 classes";
MainDocumentPart mainDocPart = doc.MainDocumentPart;
FooterPart newFooterPart = mainDocPart.AddNewPart<FooterPart>();
string rId = mainDocPart.GetIdOfPart(newFooterPart);
GeneratePageFooterPart(newFooterText).Save(newFooterPart);
foreach (SectionProperties sectProperties in
mainDocPart.Document.Descendants<SectionProperties>())
{
foreach (FooterReference footerReference in
sectProperties.Descendants<FooterReference>())
sectProperties.RemoveChild(footerReference);
FooterReference newFooterReference =
new FooterReference() { Id = rId, Type = HeaderFooterValues.Default };
sectProperties.Append(newFooterReference);
}
mainDocPart.Document.Save();
}
private static Footer GeneratePageFooterPart(string FooterText)
{
PositionalTab pTab = new PositionalTab()
{
Alignment = AbsolutePositionTabAlignmentValues.Center,
RelativeTo = AbsolutePositionTabPositioningBaseValues.Margin,
Leader = AbsolutePositionTabLeaderCharValues.None
};
var elment =
new Footer(
new Paragraph(
new ParagraphProperties(
new ParagraphStyleId() { Val = "Footer" }),
new Run(pTab,
new Text(FooterText))
)
);
return elment;
}
}
I tried some other examples too for generating the footer, but the results were the same: generated but WITHOUT footer.
What could be the problem ?
This is how you can add footer to a docx file:
static void Main(string[] args)
{
using (WordprocessingDocument document =
WordprocessingDocument.Open("Document.docx", true))
{
MainDocumentPart mainDocumentPart = document.MainDocumentPart;
// Delete the existing footer parts
mainDocumentPart.DeleteParts(mainDocumentPart.FooterParts);
// Create a new footer part
FooterPart footerPart = mainDocumentPart.AddNewPart<FooterPart>();
// Get Id of footer part
string footerPartId = mainDocumentPart.GetIdOfPart(footerPart);
GenerateFooterPartContent(footerPart);
// Get SectionProperties and Replace FooterReference with new Id
IEnumerable<SectionProperties> sections =
mainDocumentPart.Document.Body.Elements<SectionProperties>();
foreach (var section in sections)
{
// Delete existing references to headers and footers
section.RemoveAllChildren<FooterReference>();
// Create the new header and footer reference node
section.PrependChild<FooterReference>(
new FooterReference() { Id = footerPartId });
}
}
}
static void GenerateFooterPartContent(FooterPart part)
{
Footer footer1 = new Footer();
Paragraph paragraph1 = new Paragraph();
ParagraphProperties paragraphProperties1 = new ParagraphProperties();
ParagraphStyleId paragraphStyleId1 = new ParagraphStyleId() { Val = "Footer" };
paragraphProperties1.Append(paragraphStyleId1);
Run run1 = new Run();
Text text1 = new Text();
text1.Text = "Footer";
run1.Append(text1);
paragraph1.Append(paragraphProperties1);
paragraph1.Append(run1);
footer1.Append(paragraph1);
part.Footer = footer1;
}
I found the solution here is the code that works to add a paragraph below the bookmark using openxml.Below is the code that works:
var mainPart = wDoc.MainDocumentPart;
var res = from bm in mainPart.Document.Body.Descendants<BookmarkStart>()
where bm.Name == "vendos_tekstin"
select bm;
var bookmark = res.SingleOrDefault();
if (bookmark != null)
{
var parent = bookmark.Parent; // bookmark's parent element
// build paragraph piece by piece
Text text = new Text(DateTime.Now.ToString() + " , ");
Text text1 = new Text(gjenerimi + " , ");
Text text2 = new Text(merreshifren());
var run = new Run();
run.Append(text,text1,text2);
Paragraph newParagraph = new Paragraph(run);
run.PrependChild<RunProperties>(runProp);
// insert after bookmark parent
parent.InsertAfterSelf(newParagraph);
I am using OpenXML to manipulate Microsoft Word files (.docx).
I am sending the Word files as memory stream, editing them and then send them back to browser so they open in client office program.
I want to insert text, approximatley 10 lines, at the start of a document which already got content. I am doing it like this;
using (var wordprocessingDocument = WordprocessingDocument.Open(mem, true))
{
Paragraph firstParagraph = wordprocessingDocument.MainDocumentPart.Document.Descendants<Paragraph>().First();
Run run1 = new Run();
Text text1 = new Text();
text1.Text = "Document type: ";
run1.Append(text1);
Run run2 = new Run();
Break break1 = new Break();
run2.Append(break1);
ProofError proofError1 = new ProofError() { Type = ProofingErrorValues.SpellStart };
Run run3 = new Run();
Text text2 = new Text();
text2.Text = "Document ID";
run3.Append(text2);
ProofError proofError2 = new ProofError() { Type = ProofingErrorValues.SpellEnd };
Run run4 = new Run();
Break break2 = new Break();
Text text3 = new Text();
text3.Text = "Document Title";
run4.Append(break2);
run4.Append(text3);
firstParagraph.Append(run1);
firstParagraph.Append(run2);
firstParagraph.Append(proofError1);
firstParagraph.Append(run3);
firstParagraph.Append(proofError2);
firstParagraph.Append(run4);
Paragraph paragraph3 = new Paragraph() { RsidParagraphAddition = "0068718C", RsidParagraphProperties = "0068718C", RsidRunAdditionDefault = "00E1050C" };
Run run5 = new Run();
Text text4 = new Text();
text4.Text = "A";
run5.Append(text4);
Run run6 = new Run() { RsidRunAddition = "00126F2D" };
Text text5 = new Text();
text5.Text = "tlet";
run6.Append(text5);
paragraph3.Append(run5);
paragraph3.Append(run6);
Paragraph paragraph4 = new Paragraph() { RsidParagraphMarkRevision = "0068718C", RsidParagraphAddition = "00E1050C", RsidParagraphProperties = "0068718C", RsidRunAdditionDefault = "00E1050C" };
BookmarkStart bookmarkStart1 = new BookmarkStart() { Name = "_GoBack", Id = "0" };
BookmarkEnd bookmarkEnd1 = new BookmarkEnd() { Id = "0" };
paragraph4.Append(bookmarkStart1);
paragraph4.Append(bookmarkEnd1);
SectionProperties sectionProperties1 = new SectionProperties() { RsidRPr = "0068718C", RsidR = "00E1050C", RsidSect = "000C7A63" };
}
My problem is that if I already got some text from the first line, then my text will be appended after the original text there. How can I push the original content some lines down, and insert my text above?
Use PrependChild instead of Append. Append will always insert at the end of the current element. So if you already have content in the first paragraph your append will put your text at the end of it. You can also insert your text as a new first paragraph by calling Document.PrependChild(firstParagraph)
I was wondering how would it be possible to split the word document into two columns. The reason why I want to do this is because I want to be able to fit all of the information on one page.
Thank you so much for your help and time!
My Code
using (WordprocessingDocument wordDoc = WordprocessingDocument.Create(filepath, WordprocessingDocumentType.Document))
{
MainDocumentPart mainPart = wordDoc.AddMainDocumentPart();
mainPart.Document = new Document();
var margin_size = 100;
PageMargin pargeMargins = new PageMargin();
pargeMargins.Top = margin_size;
pargeMargins.Bottom = margin_size;
SectionProperties sectionProps = new SectionProperties();
sectionProps.Append(pargeMargins);
Body body = mainPart.Document.AppendChild(new Body());
body.Append(sectionProps);
ParagraphProperties paragraphProperties = new ParagraphProperties
(
//new ParagraphStyleId() { Val = "No Spacing" },
new SpacingBetweenLines() { After = "0" }
);
Paragraph para_main = body.AppendChild(new Paragraph(paragraphProperties));
// Creating the Header where the Serial Number will exist
// Serial Number
Run run_mainHeader = para_main.AppendChild(new Run());
RunProperties runProp_mainHeader = new RunProperties(); // Create run properties.
FontSize size_mainHeader = new FontSize();
size_mainHeader.Val = new StringValue("48");
runProp_mainHeader.Append(size_mainHeader);
run_mainHeader.Append(runProp_mainHeader); // Append all of the properties
run_mainHeader.Append(new Text("S/N: " + sn));
// Serial Barcode
Run run_barcode = para_main.AppendChild(new Run());
RunProperties runProp_barcode = new RunProperties(); // Create run properties.
RunFonts runFontMain_barcode = new RunFonts(); // Create font
runFontMain_barcode.Ascii = "Code39AzaleaNarrow1"; // Specify font family
FontSize size_barcode = new FontSize();
size_barcode.Val = new StringValue("48");
runProp_barcode.Append(runFontMain_barcode);
runProp_barcode.Append(size_barcode);
run_barcode.PrependChild<RunProperties>(runProp_barcode);
sn = sn.ToUpper(); // Sets all the values to uppercase to be a barcode format
run_barcode.AppendChild(new Text("*" + sn + "*"));
run_barcode.AppendChild(new Break());
// Tube Type
Run run_tubetype = para_main.AppendChild(new Run());
RunProperties runProp_tubetype = new RunProperties(); // Create run properties.
FontSize size_tubetype = new FontSize();
size_tubetype.Val = new StringValue("38");
runProp_tubetype.Append(size_tubetype);
run_tubetype.Append(runProp_tubetype); // Append all of the properties
run_tubetype.Append(new Text("Tube Type: " + forms[0].TubeType + " "));
//run_tubetype.Append(new Break());
// Tube Barcode
Run run_barcode_tube = para_main.AppendChild(new Run());
RunProperties runProp_barcode_tube = new RunProperties(); // Create run properties.
RunFonts runFontMain_barcode_tube = new RunFonts(); // Create font
runFontMain_barcode_tube.Ascii = "Code39AzaleaNarrow1"; // Specify font family
FontSize size_barcode_tube = new FontSize();
size_barcode_tube.Val = new StringValue("48");
runProp_barcode_tube.Append(runFontMain_barcode_tube);
runProp_barcode_tube.Append(size_barcode_tube);
run_barcode_tube.PrependChild<RunProperties>(runProp_barcode_tube);
sn = sn.ToUpper(); // Sets all the values to uppercase to be a barcode format
run_barcode_tube.AppendChild(new Text("*" + forms[0].TubeType + "*"));
run_barcode_tube.AppendChild(new Break());
// Goes through all of the forms
foreach (var form in forms)
{
// Set up a header per form
Run run_header = para_main.AppendChild(new Run());
RunProperties runProp_formHeader = new RunProperties();
Bold bold = new Bold();
Underline ul = new Underline() { Val = DocumentFormat.OpenXml.Wordprocessing.UnderlineValues.Single };
FontSize size_formHeader = new FontSize();
size_formHeader.Val = new StringValue("24");
runProp_formHeader.Append(size_formHeader);
runProp_formHeader.Append(bold);
runProp_formHeader.Append(ul);
run_header.AppendChild(new RunProperties(runProp_formHeader));
//run_header.AppendChild(new RunProperties(new Bold(), new Underline()));
string username = form.Username;
string proces_header = form.HeaderTitle;
run_header.AppendChild(new Text(proces_header));
run_header.AppendChild(new Break());
// Goes through all of the fields that each form contains.
for (int i = 0; i < form.FieldList.Count; i++)
{
// Do not need to print out user or serial for each form.
if (!(form.FieldList[i].Token == "SNT"))
{
Run run_data = para_main.AppendChild(new Run());
if (form.FieldList[i].Default)
{
run_data.AppendChild(new Text(form.FieldList[i].Label));
}
else
{
run_data.AppendChild(new Text(form.FieldList[i].Label + " " + form.FieldList[i].Spec + form.FieldList[i].Value));
}
run_data.AppendChild(new Break());
}
}
}
mainPart.Document.Save();
wordDoc.Close();
return "Success";
}
Currently the code prints out everything top-down on one column. And I want it with two columns
You can two or how many columns you want using the Columns Class for the SectionProperties and ParagraphProperties Class
http://msdn.microsoft.com/en-us/library/documentformat.openxml.wordprocessing.columns(v=office.14).aspx
http://msdn.microsoft.com/en-us/library/documentformat.openxml.wordprocessing.paragraphproperties(v=office.14).aspx
http://msdn.microsoft.com/en-us/library/documentformat.openxml.wordprocessing.sectionproperties(v=office.14).aspx
This should do it:
// Add a new main document part.
package.AddMainDocumentPart();
// Create the Document DOM.
package.MainDocumentPart.Document = new Document();
Body bd = package.MainDocumentPart.Document.Body = new Body();
//write a first paragraph on two columns
var paragrap1 = new Paragraph();
var paragraphSectionProperties = new ParagraphProperties(new SectionProperties());
var paragraphColumns = new Columns();
paragraphColumns.EqualWidth = true;
paragraphColumns.ColumnCount = 2;
paragraphSectionProperties.Append(paragraphColumns);
paragrap1.Append(paragraphSectionProperties);
paragrap1.Append(new Run(new Text(str)));
bd.AppendChild(paragrap1);
//write another paragraph without paragraph properties
bd.Append(new Paragraph(new Run(new Text(str))));
//set the body properties default three columns
var sectionProperties = new SectionProperties();
var columns = new Columns();
columns.EqualWidth = true;
columns.ColumnCount = 3;
sectionProperties.Append(columns);
bd.Append(sectionProperties);
package.MainDocumentPart.Document.Save();
You can do it for the complete document with this code:
var sectionProperty = document.Body.Descendants<SectionProperties>().First();
var paragraphColumns = new Columns {EqualWidth = true, ColumnCount = 2};
sectionProperty.Append(paragraphColumns);
Try with..
Word.Application WordApp = new Word.Application();
Word.Document BaseDoc = default(Word.Document);
Word.Document DestDoc = default(Word.Document);
int intNumberOfPages = 0;
string intNumberOfChars = null;
int intPage = 0;
//Word Constants
const var wdGoToPage = 1;
const var wdStory = 6;
const var wdExtend = 1;
const var wdCharacter = 1;
//Show WordApp
WordApp.ShowMe();
//Load Base Document
BaseDoc = WordApp.Documents.Open(Filename);
BaseDoc.Repaginate();
//Loop through pages
intNumberOfPages = BaseDoc.BuiltInDocumentProperties("Number of Pages").value;
intNumberOfChars = BaseDoc.BuiltInDocumentProperties("Number of Characters").value;
for (intPage = 1; intPage <= intNumberOfPages; intPage++) {
if (intPage == intNumberOfPages) {
WordApp.Selection.EndKey(wdStory); }
else {
WordApp.Selection.GoTo(wdGoToPage, 2);
Application.DoEvents();
WordApp.Selection.MoveLeft(Unit = wdCharacter, Count = 1);
}
Application.DoEvents();
WordApp.Selection.HomeKey(wdStory, wdExtend);
Application.DoEvents();
WordApp.Selection.Copy();
Application.DoEvents();
//Create New Document
DestDoc = WordApp.Documents.Add;
DestDoc.Activate();
WordApp.Selection.Paste();
DestDoc.SaveAs(NewFileName + intPage.ToString + ".doc");
DestDoc.Close();
DestDoc = null;
WordApp.Selection.GoTo(wdGoToPage, 2);
Application.DoEvents();
WordApp.Selection.HomeKey(wdStory, wdExtend);
Application.DoEvents();
WordApp.Selection.Delete();
Application.DoEvents();
}
BaseDoc.Close(false);
BaseDoc = null;
WordApp.Quit();
WordApp = null;
How would I align my table in the middle of the word document in open xml?
Here is my code and I want to align the table in the middle.
Here is my code. I'm trying to use TableJustification, but it seems like its not working
using (WordprocessingDocument wordDoc = WordprocessingDocument.Create(filepath, WordprocessingDocumentType.Document))
{
MainDocumentPart mainPart = wordDoc.AddMainDocumentPart();
mainPart.Document = new Document();
Body body = mainPart.Document.AppendChild(new Body());
Run run = new Run();
// Goes through all of the forms
foreach (var form in forms)
{
Table table = new Table();
// Initialize all of the table properties
TableProperties tblProp = new TableProperties(
new TableBorders(
new TopBorder() { Val = new EnumValue<BorderValues>(BorderValues.BasicBlackSquares), Size = 16 },
new LeftBorder() { Val = new EnumValue<BorderValues>(BorderValues.BasicBlackSquares), Size = 16 },
new RightBorder() { Val = new EnumValue<BorderValues>(BorderValues.BasicBlackSquares), Size = 16 },
new BottomBorder() { Val = new EnumValue<BorderValues>(BorderValues.BasicBlackSquares), Size = 16 }
)
);
// Align the table to the center
TableJustification justs_center = new TableJustification() { Val = _____ };
table.AppendChild(justs_center);
table.AppendChild<TableProperties>(tblProp);
Paragraph para = body.AppendChild(new Paragraph());
Run run_header = para.AppendChild(new Run());
RunProperties runProps = run_header.AppendChild(new RunProperties(new Bold()));
string username = form.Username;
string proces_header = form.HeaderTitle;
run_header.AppendChild(new Text(proces_header + " | " + username));
for (int i = 0; i < form.FieldList.Count; i++)
{
if (!(form.FieldList[i].Token == "USR" || form.FieldList[i].Token == "SNT"))
{
TableRow tr = new TableRow();
TableCell header_cell = new TableCell();
header_cell.Append(new Paragraph(new Run(new Text(form.FieldList[i].Label + ": " + form.FieldList[i].Value))));
tr.Append(header_cell);
table.Append(tr);
}
}
wordDoc.MainDocumentPart.Document.Body.Append(table);
}
mainPart.Document.Save();
wordDoc.Close();
return "Success";
}
}
Table t = new Table(
new TableProperties(
...
new TableJustification() { Val = TableRowAlignmentValues.Center},
...),
new TableRow(...),
);
Trying to center the table with the accepted answer did not seem to work. I needed to apply the center justification to all of the rows as well
var t = new Table();
var tableProps = new TableProperties();
tableProps.TableJustification = new TableJustification { Val = TableRowAlignmentValues.Center };
t.Append(tableProps);
var row = new TableRow();
var rowProps = new TableRowProperties();
rowProps.Append(new TableJustification { Val = TableRowAlignmentValues.Center });
row.Append(rowProps);
Found using the Open XML Productivity Tool
Actually, you need to apply the center justification to all rows in TableRowProperties only. Even if you don't apply justification in TableProperties, the table will be centered anyway. And I'm interested to find out what is the purpose of justification in TableRowProperties if someone knows.