Implementing table insertion into Word using Office for JS (officejs) - ms-word

Working on a project aiming to convert some C# based Word Add-in into JavaScript using officejs.
Quite surprised that after 5 years of development officejs API is not quite there in terms of coverage compared to C# API.
I am struggling how to translate the following C# Word API code into JavaScript based API. Seems that a lot of functionality is simply not there.
How can the following code be converted to Javascript to achieve the same level of end state functionality?
MsWord.Table tblchart = rng.Tables.Add(rng, NumRows: 1, NumColumns: 1,
AutoFitBehavior: MsWord.WdAutoFitBehavior.wdAutoFitFixed);
tblchart.AllowPageBreaks = false;
tblchart.Borders.OutsideLineStyle = WdLineStyle.wdLineStyleNone;
tblchart.Borders.InsideLineStyle = WdLineStyle.wdLineStyleNone;
tblchart.Borders.Shadow = false;
tblchart.TopPadding = tblchart.BottomPadding = tblchart.LeftPadding = 0f;
tblchart.RightPadding = application.InchesToPoints(0.02f);
tblchart.PreferredWidthType = MsWord.WdPreferredWidthType.wdPreferredWidthPoints;
tblchart.set_Style(WordStyles.Table);
tblchart.Range.set_Style(WordStyles.TableMaster);
tblchart.Rows.WrapAroundText = System.Convert.ToInt32(false);
tblchart.PreferredWidth = _Imagewidth;
tblchart.Descr = _description;
tblchart.Rows[1].AllowBreakAcrossPages = 0;
tblchart.Rows[1].Range.set_Style(WordStyles.Figure);
tblchart.Rows[1].Range.Text = "";
tblchart.Rows.SetLeftIndent(LeftIndent: application.InchesToPoints(_leftIndent), RulerStyle: WdRulerStyle.wdAdjustNone);

Related

Concatenate multiple PDF/A with different conformance levels

Is it possible to concatenate a number of pdf/a (with possibly different conformance levels: some pdf/a-1b, some pdf/a-3b ecc) into a single pdfa ?
I was thinking that using the latest level (3-a or 3b) would be ok but I get errors when validating with VeraPDF:
Here is my code (where :
public static byte[] CreateConformantCopy(List<byte[]> sourcePdfs)
{
var version = PdfVersion.PDF_1_7;
var type = PdfAType.PDF_A_3B;
WriterProperties wp = new WriterProperties();
wp.UseSmartMode();
wp.SetPdfVersion(version.ToPdfVersion());
PdfOutputIntent oi = new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", Assembly.GetExecutingAssembly().GetManifestResourceStream("xxx.Resources.sRGB_CS_profile.icm"));
using (var mergedPdf = new MemoryStream())
{
var writer = new PdfWriter(mergedPdf, wp);
using (PdfADocument newDoc = new PdfADocument(writer, type.ToPdfAConformanceLevel(), oi, new DocumentProperties() { }))
{
Document document = new Document(newDoc, PageSize.A4.Rotate());
newDoc.SetTagged();
newDoc.GetCatalog().SetLang(new PdfString(Thread.CurrentThread.CurrentUICulture.Name));
newDoc.GetCatalog().SetViewerPreferences(
new PdfViewerPreferences()
.SetDisplayDocTitle(true)
.SetCenterWindow(true)
);
PdfMerger merger = new PdfMerger(newDoc);
for (int k = 0; k < sourcePdfs.Count; k++)
{
using (var inDoc = PdfHelper.GetDocument(sourcePdfs[k]))
{
var numberOfPages = inDoc.GetNumberOfPages();
merger.Merge(inDoc, 1, numberOfPages);
}
}
newDoc.Close();
}
return mergedPdf.ToArray();
}
}
PDF/A-1 and PDF/A-2 have several differences in the requirements. So, merging them together might not be possible. Looking on your validation errors, I think this is exactly the case. For example, the very first one is about XMP metadata. The PDF/A-2 is more strict here, and you get this error because your first file (which is probably a valid PDF/A-1) does not actually satisfy the PDF/A-2 rules.
What is possible however is to attach a PDF/A-1 document to PDF/A-2 one. This does not even require the use of PDF/A-3, which allows arbitrary attachments. The PDF/A-2 standard does allow attaching valid PDF/A-1 (as well as PDF/A-2 documents).

Set An Alert on Sharepoint 2013 for multiple list and library

I have some sites with many list and library. I want to know about their changes. set alert for any list and library is very difficult and It takes a long time.
Is there any soloution ?
We can use create alert for all the custom list and document library using C# code or PowerShell script.
The following C# code for your reference.
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite("http://sp2013"))
{
using (SPWeb web = site.OpenWeb())
{
foreach(SPList list in web.Lists)
{
if (list.BaseType == SPBaseType.GenericList || list.BaseType == SPBaseType.DocumentLibrary)
{
SPUser user = web.EnsureUser(#"domain\admin");
SPAlert newAlert = user.Alerts.Add();
newAlert.Title = "My Custom Alert";
newAlert.AlertType = SPAlertType.List;
newAlert.List = list;
newAlert.DeliveryChannels = SPAlertDeliveryChannels.Email;
newAlert.EventType = SPEventType.Add;
newAlert.AlertFrequency = SPAlertFrequency.Immediate;
newAlert.Update();
}
}
}
}
});
Reference:
Programmatically Creating Alerts in SharePoint
Create - Edit - Find - Delete SharePoint Alerts using PowerShell

SharePoint 2013 REST API - Post SocialRestPostCreationData

I’m currently working on a small application to push Post to a SharePoint 2013 SiteFeed using the Social.Feed API.
Basic Posts using the following JSON Object structure are working fine but I’m struggling using a Social-Attachment.
As long I’m referencing to the files located somewhere in the internet everything works. Posts will create listitems in micro-feed list with HTTP-Reference to the Files. The Object I'm using is set up like this
var creationInfo = new
{
restCreationData = new
{
__metadata = new { type = "SP.Social.SocialRestPostCreationData" },
ID = array,
creationData = new
{
__metadata = new { type = "SP.Social.SocialPostCreationData" },
Attachment = new
{
__metadata = new { type = "SP.Social.SocialAttachment" },
AttachmentKind = 0,
ContentUri = "https://www.google.com/images/icons/hpcg/ribbon-black_68.png",
Description = "Look at this",
Name = "Test",
Uri = "https://www.google.com/images/icons/hpcg/ribbon-black_68.png"
},
ContentText = text,
UpdateStatusText = false,
}
}
};
Is there a possibility to use a local file instead? - Removing the google paths and using a local path in ContentUri will end up in a BAD-Request error.
I guess that the files has to be uploaded somehow before.
Thanks for you help.
Iki
After some trying we now ended up with the following solution.
Before we create the SocialPost, we upload the picture into an image gallery where all Feed users have access to.
Then we create the post containing a link to the image
-> This will do the trick.

there.are.illegal.characters.for.barcode.128 exception when using CODE128_UCC in itextsharp 5.5.4 .net

When attempting to create an GS1-128 barcode I encounter the following exception: there.are.illegal.characters.for.barcode.128.in.1
iTextSharp.text.pdf.Barcode barcode = null;
barcode = new Barcode128();
barcode.CodeType = iTextSharp.text.pdf.Barcode.CODE128_UCC;
barcode.GenerateChecksum = true;
barcode.Code = code;
using (var image = barcode.CreateDrawingImage(Color.Black, Color.White))
After pulling down the source it looks like there might be a bug in the library the code calling into GetRawText. It will pass CodeSet Auto which fails the assertions in in the method. I determined the following to be an acceptable workaround:
iTextSharp.text.pdf.Barcode barcode = null;
barcode = new Barcode128();
barcode.CodeType = iTextSharp.text.pdf.Barcode.CODE128_RAW;
barcode.GenerateChecksum = true;
barcode.Code = Barcode128.GetRawText(code, true, Barcode128.Barcode128CodeSet.C);
using (var image = barcode.CreateDrawingImage(Color.Black, Color.White))
code.Normalize(NormalizationForm.FormKC)
Worked for me. try this.

Referencing other documents' content

We need to create a matrix from 2 other documents' contents. For example:
doc has fields like:
4.2 Requirements A
Blah
doc has fields like:
2.1 Analysis A
Blah Blah
and we want to create another document (called Traceability Matrix) which is like:
Col1 Col2 Col3
4.2 2.1 Blah Blah Blah
4.2 and 2.1 should be dynamically updated in doc3.
We checked using hyperlink, cross referencing but nothing seems to be useful for combining different documents. Is there anyway to do this?
EDIT:
Here is an example:
Technical Specification Num Requirement Num Requirement
4.2 2.1 A sentence that explains the relationship btw 2 cols: Technical Specification and Requirement Num
I have now created a working example of how this can be implemented using MS Word Interop and C#.
The code contains comments that should explain the most interesting parts.
The sample is implemented as a C# console application using:
.NET 4.5
Microsoft Office Object Library version 15.0, and
Microsoft Word Object Library version 15.0
... that is, the MS Word Interop API that ships with MS Office 2013 Preview.
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Office.Interop.Word;
using Application = Microsoft.Office.Interop.Word.Application;
namespace WordDocStats
{
internal class Program
{
private static void Main()
{
// Open word
var wordApplication = new Application() { Visible = true };
// Open document A, get its headings, and close it again
var documentA = wordApplication.Documents.Open(#"C:\Users\MyUserName\Documents\documentA.docx", Visible: true);
var headingsA = GetHeadingsInDocument(documentA);
documentA.Close();
// Same procedure for document B
var documentB = wordApplication.Documents.Open(#"C:\Users\MyUserName\Documents\documentB.docx", Visible: true);
var headingsB = GetHeadingsInDocument(documentB);
documentB.Close();
// Open the target document (document C)
var documentC = wordApplication.Documents.Open(#"C:\Users\MyUserName\Documents\documentC.docx", Visible: true);
// Add a table to it (the traceability matrix)
// The number of rows is the number of headings + one row reserved for a table header
documentC.Tables.Add(documentC.Range(0, 0), headingsA.Count+1, 3);
// Get the traceability matrix
var traceabilityMatrix = documentC.Tables[1];
// Add a table header and border
AddTableHeaderAndBorder(traceabilityMatrix, "Headings from document A", "Headings from document B", "My Description");
// Insert headings from doc A and doc B into doc C's traceability matrix
for (var i = 0; i < headingsA.Count; i++)
{
// Insert headings from doc A
var insertRangeColOne = traceabilityMatrix.Cell(i + 2, 1).Range;
insertRangeColOne.Text = headingsA[i].Trim();
// Insert headings from doc B
var insertRangeColTwo = traceabilityMatrix.Cell(i + 2, 2).Range;
insertRangeColTwo.Text = headingsB[i].Trim();
}
documentC.Save();
documentC.Close();
wordApplication.Quit();
}
// Based on:
// -> http://csharpfeeds.com/post/5048/Csharp_and_Word_Interop_Part_4_-_Tables.aspx
// -> http://stackoverflow.com/a/1817041/700926
private static void AddTableHeaderAndBorder(Table table, params string[] columnTitles)
{
const int headerRowIndex = 1;
for (var i = 0; i < columnTitles.Length; i++)
{
var tableHeaderRange = table.Cell(headerRowIndex, i+1).Range;
tableHeaderRange.Text = columnTitles[i];
tableHeaderRange.Font.Bold = 1;
tableHeaderRange.Font.Italic = 1;
}
// Repeat header on each page
table.Rows[headerRowIndex].HeadingFormat = -1;
// Enable borders
table.Borders.Enable = 1;
}
// Based on:
// -> http://stackoverflow.com/q/7084270/700926
// -> http://stackoverflow.com/a/7084442/700926
private static List<string> GetHeadingsInDocument(Document document)
{
object headingsAtmp = document.GetCrossReferenceItems(WdReferenceType.wdRefTypeHeading);
return ((Array)(headingsAtmp)).Cast<string>().ToList();
}
}
}
Basically, the code first loads all headings from the two given documents and stores them in memory. Then it opens the target document, creates and styles the traceability matrix, and finally, it inserts the headings into the matrix.
The code is based on the assumptions that:
A target document (documentC.docx) exists.
The number of headings in the two input documents (documentA.docx, and documentB.docx) contains the same amount of headings - this assumption is made based on your comment about not wanting a Cartesian product.
I hope this meets your requirements :)