OpenXml can't open docx file after vertically merged cells, - openxml-sdk

string path = #"D:\newdoc.docx" ;
using (WordprocessingDocument doc = WordprocessingDocument.Create(path, WordprocessingDocumentType.Document))
{
MainDocumentPart mainpart = doc.AddMainDocumentPart();
mainpart.Document = new Document();
Body body = mainpart.Document.AppendChild(new Body());
Table t = new Table();
TableProperties tpr = new TableProperties(new TableWidth(){Width="0",Type=TableWidthUnitValues.Auto},new TableLook(){Val="04A0"});
t.Append(tpr);
TableGrid tg = new TableGrid(new GridColumn() { Width = "4261" }, new GridColumn() { Width = "4261" });
t.Append(tg);
TableRow tr1 = new TableRow();
TableCell r1tc1 = new TableCell();
TableCell r1tc2 = new TableCell();
tr1.Append(r1tc1);
tr1.Append(r1tc2);
TableRow tr2 = new TableRow();
TableCell r2tc1 = new TableCell();
TableCell r2tc2 = new TableCell();
tr2.Append(r2tc1);
tr2.Append(r2tc2);
TableRow tr3 = new TableRow();
TableCell r3tc1 = new TableCell();
TableCellProperties r3tc1prp = new TableCellProperties();
VerticalMerge vm = new VerticalMerge() { Val = MergedCellValues.Restart };
r3tc1prp.Append(vm);
r3tc1.Append(r3tc1prp);
TableCell r3tc2 = new TableCell(new TableCellProperties());
tr3.Append(r3tc1);
tr3.Append(r3tc2);
TableRow tr4 = new TableRow();
TableCell r4tc1 = new TableCell();
r4tc1.TableCellProperties = new TableCellProperties(new TableCellWidth() { Width = "4261", Type = TableWidthUnitValues.Dxa });
r4tc1.TableCellProperties.VerticalMerge = new VerticalMerge();
TableCell r4tc2 = new TableCell();
tr4.Append(r4tc1);
tr4.Append(r4tc2);
t.Append(tr1);
t.Append(tr2);
t.Append(tr3);
t.Append(tr4);
body.Append(t);
}
after create and saved the document, I can't open it with Word2007
Error:<p> element must before element </tc>
I can't find <p> element in document.xml
troubled me for several days ,anyone can help thxs

The fact that you can't find the <p> element in your document is actually the problem. The schema expects a Paragraph element in every TableCell; without the Paragraph the document is invalid. This leads to the rather cryptic error that you must have a <p> (open paragraph element) before a </tc> (close table cell element).
Adding a Paragraph to each TableCell you create will solve your problem. The easiest way to do that is to pass a new Paragraph to each TableCell constructor:
string path = #"D:\newdoc.docx";
using (WordprocessingDocument doc = WordprocessingDocument.Create(path, WordprocessingDocumentType.Document))
{
MainDocumentPart mainpart = doc.AddMainDocumentPart();
mainpart.Document = new Document();
Body body = mainpart.Document.AppendChild(new Body());
Table t = new Table();
TableProperties tpr = new TableProperties(new TableWidth() { Width = "0", Type = TableWidthUnitValues.Auto }, new TableLook() { Val = "04A0" });
t.Append(tpr);
TableGrid tg = new TableGrid(new GridColumn() { Width = "4261" }, new GridColumn() { Width = "4261" });
t.Append(tg);
TableRow tr1 = new TableRow();
TableCell r1tc1 = new TableCell(new Paragraph());
TableCell r1tc2 = new TableCell(new Paragraph());
tr1.Append(r1tc1);
tr1.Append(r1tc2);
TableRow tr2 = new TableRow();
TableCell r2tc1 = new TableCell(new Paragraph());
TableCell r2tc2 = new TableCell(new Paragraph());
tr2.Append(r2tc1);
tr2.Append(r2tc2);
TableRow tr3 = new TableRow();
TableCell r3tc1 = new TableCell(new Paragraph());
TableCellProperties r3tc1prp = new TableCellProperties();
VerticalMerge vm = new VerticalMerge() { Val = MergedCellValues.Restart };
r3tc1prp.Append(vm);
r3tc1.Append(r3tc1prp);
TableCell r3tc2 = new TableCell(new Paragraph(), new TableCellProperties());
tr3.Append(r3tc1);
tr3.Append(r3tc2);
TableRow tr4 = new TableRow();
TableCell r4tc1 = new TableCell(new Paragraph());
r4tc1.TableCellProperties = new TableCellProperties(new TableCellWidth() { Width = "4261", Type = TableWidthUnitValues.Dxa });
r4tc1.TableCellProperties.VerticalMerge = new VerticalMerge();
TableCell r4tc2 = new TableCell(new Paragraph());
tr4.Append(r4tc1);
tr4.Append(r4tc2);
t.Append(tr1);
t.Append(tr2);
t.Append(tr3);
t.Append(tr4);
body.Append(t);
}

Related

How to check if enabling custom invoice numbers results in duplicate invoice Numbers

I am working on integrating quick books with mvc and I have to work on one task which is to check if enabling custom invoice numbers results in duplicate Invoice .
I have tried creating invoice in quick books
public Invoice PostInvoice(InvoiceViewModel model)
{
Intuit.Ipp.Data.Invoice invoice = new Intuit.Ipp.Data.Invoice();
invoice.Deposit = new Decimal(0.00);
invoice.DepositSpecified = true;
invoice.DocNumber = "QBOInvoice" + DateTime.Now.ToString("MMddHHmmss");
invoice.CustomerRef = new ReferenceType { Value = model.qboCustomer.Id };
// invoice.CustomerMemo = new MemoRef { Value = reference };
invoice.DueDate = DateTime.UtcNow.Date;
invoice.DueDateSpecified = true;
invoice.TotalAmtSpecified = true;
invoice.ApplyTaxAfterDiscount = false;
invoice.ApplyTaxAfterDiscountSpecified = true;
invoice.PrintStatus = PrintStatusEnum.NotSet;
invoice.PrintStatusSpecified = true;
invoice.EmailStatus = EmailStatusEnum.NotSet;
invoice.EmailStatusSpecified = true;
invoice.BalanceSpecified = true;
invoice.TxnDate = DateTime.UtcNow.Date;
invoice.TxnDateSpecified = true;
invoice.ShipAddr = model.Address;
invoice.BillAddr = model.Address; //new PhysicalAddress() { Line1 = "BillMohali", Line2 = "Sector 70 ", City = "Mohali", PostalCode = "160071" };
//invoice.ShipAddr = new PhysicalAddress() {Line1="Mohali", Line2="Sector 70 ",City="Mohali",PostalCode="160071" };
//invoice.BillAddr = new PhysicalAddress() { Line1 = "BillMohali", Line2 = "Sector 70 ", City = "Mohali", PostalCode = "160071" };
Intuit.Ipp.Data.Line line = new Intuit.Ipp.Data.Line();
SalesItemLineDetail lineSalesItemLineDetail = new SalesItemLineDetail();
List<Intuit.Ipp.Data.Line> lineList = new List<Intuit.Ipp.Data.Line>();
foreach (var item in model.qbolineitems)
{
lineSalesItemLineDetail = new SalesItemLineDetail();
line = new Intuit.Ipp.Data.Line();
//Line Sales Item Line Detail - ServiceDate
lineSalesItemLineDetail.ServiceDate = DateTime.Now.Date;
lineSalesItemLineDetail.ServiceDateSpecified = true;
lineSalesItemLineDetail.Qty = item.invoiceitem.quantity.Value;
lineSalesItemLineDetail.QtySpecified = true;
lineSalesItemLineDetail.ItemRef = new ReferenceType { Value = item.item.qboItemCode.Value.ToString(), name = item.item.qboItemName };
lineSalesItemLineDetail.AnyIntuitObject = item.invoiceitem.SalePrice.Value / item.invoiceitem.quantity.Value;
lineSalesItemLineDetail.ItemElementName = ItemChoiceType.UnitPrice;
line.AnyIntuitObject = lineSalesItemLineDetail;
line.Description = item.item.qboItemName;
line.Amount = item.invoiceitem.SalePrice.Value;
line.AmountSpecified = true;
// line.Id = item.item.qboItemCode.Value.ToString();
line.DetailType = LineDetailTypeEnum.SalesItemLineDetail;
line.DetailTypeSpecified = true;
//if (_connect.Country == "US")
//{
lineSalesItemLineDetail.TaxInclusiveAmt = item.invoiceitem.SalePrice.Value;
lineSalesItemLineDetail.TaxCodeRef = new ReferenceType { Value = "TAX" };
//}
//else
//{
//_connect = (Connect)Session["Connect"];
// objQBO = new QBOWrapper("jagjeetkr7#gmail.com", Request.Url.GetLeftPart(UriPartial.Authority) + "/Home/Callback", _connect, true);
//var taxcode = objQBO.getTaxCodeList().Where(x => x.Active).FirstOrDefault();
//lineSalesItemLineDetail.TaxCodeRef = new ReferenceType { Value = taxcode.Id };
//var dis = item.invoiceitem.SalePrice.Value / (Convert.ToDecimal(taxcode.SalesTaxRateList.TaxRateDetail[0].TaxRateRef.Value) + 1);
//line.Amount = item.invoiceitem.SalePrice.Value - dis;
//lineSalesItemLineDetail.TaxInclusiveAmt = item.invoiceitem.SalePrice.Value;
lineSalesItemLineDetail.TaxInclusiveAmtSpecified = false;
invoice.GlobalTaxCalculationSpecified = false;
invoice.GlobalTaxCalculation = GlobalTaxCalculationEnum.NotApplicable;
//SendInsideFunctionEmail("Failed to create surcharge invoice for : " + reference, "Please create a surcharge invoice manually and send a receipt to the customer. Also,please assign the tax code for this account selected in qbo.", _generalSettings.AccountsEmail);
// }
lineList.Add(line);
}
//invoice.TotalAmt = new Decimal(0.90);
//invoice.Balance = new Decimal(0.90);
// xlic.Add(li);
invoice.TotalAmt = model.Total;
invoice.Balance = model.BalanceDue;
invoice.Line = lineList.ToArray();
_connect = (Connect)Session["Connect"];
objQBO = new QBOWrapper("jagjeetkr7#gmail.com", Request.Url.GetLeftPart(UriPartial.Authority) + "/Home/Callback", _connect, true);
//objQBO = new QBOWrapper("jagjeetkr7#gmail.com", Request.Url.GetLeftPart(UriPartial.Authority) + "/Home/Callback", _connect, true);
invoice = objQBO.CreateInvoice(invoice);
return invoice;
}
I expect that generating custom invoice numbers results in duplicate invoice but not finding a way to implement that

Xamarin Forms Grid in a TableView

I am creating a financial app and need to show a table with section headers and many grids.
In the attached screenshot I am almost there. I need the first column to Left align (start) and the rows to be about double their default height.
var content = new TableView
{
Intent = TableIntent.Data,
Root = new TableRoot("Performance"),
BackgroundColor = Color.Green
};
content.Root.Add(GetTableSection("Monthly", Model.Monthly);
.................
private TableSection GetTableSection(string title, List<PerformanceRow> performanceRows)
{
TableSection section = new TableSection()
{
Title = title
};
foreach (var row in performanceRows)
{
Grid grid = new Grid
{
VerticalOptions = LayoutOptions.FillAndExpand,
HeightRequest = 100, //?????????
BackgroundColor = Color.Red,
ColumnDefinitions =
{
new ColumnDefinition {Width = new GridLength(.3, GridUnitType.Star)},
new ColumnDefinition {Width = new GridLength(.3, GridUnitType.Star)},
new ColumnDefinition {Width = new GridLength(.3, GridUnitType.Star)},
}
};
//First Row
grid.Children.Add(new Label {Text = row.Title, HorizontalOptions = LayoutOptions.Start}, 1, 0);
grid.Children.Add(new Label {Text = "Market Value"}, 2, 0);
grid.Children.Add(new Label {Text = row.MarketValue.ToString("C"), HorizontalOptions = LayoutOptions.End}, 3, 0);
//Second Row
grid.Children.Add(new Label {Text = " "}, 1, 1);
grid.Children.Add(new Label {Text = "Return"}, 2, 1);
grid.Children.Add(new Label {Text = row.ReturnRate.ToString("C"), HorizontalOptions = LayoutOptions.End}, 3, 1);
section.Add(new ViewCell()
{
View = grid,
Height = 100 //??????????
});
}
return section;
}
This worked:
Set the UnevenRows to true for the tableview, then the table intent to rows

Adding Bin/Lot/Serial item to Acumatica shipment lines

Adding Bin/Lot/Serial item to Acumatica shipment lines
I are able to create an Acumatica shipment through Web Services, but getting an issue in adding Bin/Lot Number for each line in the grid. If I have only one document detail line in shipment, it is working fine, but when there is more than one line in document details, the code does not seem to be working. Please find below the Acumatica code that I am using to achieve this.
SO302000Content soShipcontent = content.SO302000GetSchema();
List<Command> scmds = new List<Command>();
List<LineDetails> splits = new List<LineDetails>();
CreateShipmentHeader(soShipcontent, hparams, ref scmds, Ordernumber);
var shipmentresults = content.SO302000Submit(scmds.ToArray());
if (shipmentresults != null && shipmentresults.Length > 0)
{
int linen = 0;
List<Command> cmds = new List<Command>();
foreach (var row in shipmentresults)
{
SO302000Content c = (SO302000Content)row;
cmds.Add(new Value { Value = linen.ToString(), LinkedCommand = soShipcontent.AddSalesOrder.ServiceCommands.RowNumber });
cmds.Add(new Value { Value = "True", LinkedCommand = soShipcontent.AddSalesOrder.Selected, Commit = true });
LineDetails ld = details.Find(x => x.InventoryId == c.AddSalesOrder.InventoryID.Value.ToString().Trim());
if (ld != null)
{
LineDetails splitno = new LineDetails();
splitno.InventoryId = ld.InventoryId;
splitno.Location = ld.Location;
splitno.LotNo = ld.LotNo;
splitno.Quantity = c.AddSalesOrder.Quantity.Value.ToString().Trim();
splitno.LineNumber = (linen).ToString();
splits.Add(splitno);
}
linen++;
}
cmds.Add(soShipcontent.Actions.AddSO);
content.SO302000Submit(cmds.ToArray());
foreach (LineDetails s in splits)
{
List<Command> cmdsplit = new List<Command>();
cmdsplit.Add(new Value { Value = s.LineNumber, LinkedCommand = soShipcontent.BinLotSerialNumbers.ServiceCommands.RowNumber });
cmdsplit.Add(new Value { Value = s.InventoryId, LinkedCommand = soShipcontent.BinLotSerialNumbers.InventoryID, Commit = true });
cmdsplit.Add(new Value { Value = s.Location, LinkedCommand = soShipcontent.BinLotSerialNumbers.Location, Commit = true });
cmdsplit.Add(new Value { Value = s.LotNo, LinkedCommand = soShipcontent.BinLotSerialNumbers.LotSerialNbr });
cmdsplit.Add(new Value { Value = s.Quantity, LinkedCommand = soShipcontent.BinLotSerialNumbers.Quantity });
content.SO302000Submit(cmdsplit.ToArray());
}
}
List<Command> cmds1 = new List<Command>();
string shipmentnbr = string.Empty;
cmds1.Add(soShipcontent.Actions.Save);
cmds1.Add(soShipcontent.ShipmentSummary.ShipmentNbr);
content.SO302000Submit(cmds1.ToArray());
I have tried below code also:
cmds.Add(soShipcontent.BinLotSerialNumbers.ServiceCommands.NewRow);
cmdsplit.Add(new Value { Value = s.Location, LinkedCommand = soShipcontent.BinLotSerialNumbers.Location});
cmdsplit.Add(new Value { Value = s.LotNo, LinkedCommand = soShipcontent.BinLotSerialNumbers.LotSerialNbr });
cmdsplit.Add(new Value { Value = s.Quantity, LinkedCommand = soShipcontent.BinLotSerialNumbers.Quantity, Commit = true });
cmdsplit.Add(new Value { Value = s.InventoryId, LinkedCommand = soShipcontent.BinLotSerialNumbers.InventoryID });
cmdsplit.Add(new Key { Value = "='" + s.InventoryId + "'", FieldName = soShipcontent.DocumentDetails.InventoryID.FieldName, ObjectName = soShipcontent.DocumentDetails.InventoryID.ObjectName });
Actually i'm not really following your code but i would say that acumatica an assign SN automatically depends on the item settings. Otherwise you can manually assign SN.
The most simplest example is when you have qty = 1 on the detail level, see code below
Content[] result = context.Submit(
new Command[]
{
new Value { Value = "000200", LinkedCommand = SO302000.ShipmentSummary.ShipmentNbr, Commit = true },
//navigate to line
new Key
{
ObjectName = SO302000.DocumentDetails.InventoryID.ObjectName,
FieldName = SO302000.DocumentDetails.InventoryID.FieldName,
Value = "='INCLUTA009'"
},
new Value { Value = "20SP0610", LinkedCommand = SO302000.DocumentDetails.LotSerialNbr, Commit = true },
SO302000.Actions.Save
}
);

How to copy one spreadsheet's cell to another spreadsheet

I tried coding like spreadsheet API batch copy https://developers.google.com/google-apps/spreadsheets/#updating_multiple_cells_with_a_batch_request, The sample is base on same spreadsheet, I added a target cell but always get same error
com.google.gdata.client.batch.BatchInterruptedException: Batch Interrupted (some operations might have succeeded) : a response has already been sent for batch operation update id='R1C1'
My code like this
SpreadsheetService spreadsheetService = getSpreadsheetService(currentEmail);
WorksheetFeed feed = spreadsheetService.getFeed(getWorksheetFeedURL(sourceId), WorksheetFeed.class);
SpreadsheetEntry targetFeed = spreadsheetService.getEntry(getSpreadsheetFeedURL(targetId), SpreadsheetEntry.class);
SpreadsheetEntry sourceFeed = spreadsheetService.getEntry(getSpreadsheetFeedURL(sourceId), SpreadsheetEntry.class);
for(WorksheetEntry entry:feed.getEntries()){
WorksheetEntry targetWorksheet = spreadsheetService.insert(targetFeed.getWorksheetFeedUrl(), entry);
FeedURLFactory urlFactory = FeedURLFactory.getDefault();
URL cellFeedUrl = urlFactory.getCellFeedUrl(sourceFeed.getKey(), "od6", "private", "full");
URL targetFeedUrl = urlFactory.getCellFeedUrl(targetFeed.getKey(), "od6", "private", "full");
CellFeed cellFeed = spreadsheetService.getFeed(targetFeedUrl, CellFeed.class);
List<CellAddress> cellAddrs = new ArrayList<CellAddress>();
for (int row = 1; row <= entry.getRowCount(); ++row) {
for (int col = 1; col <= entry.getColCount(); ++col) {
cellAddrs.add(new CellAddress(row, col));
}
}
Map<String, CellEntry> cellEntries = getCellEntryMap(spreadsheetService, cellFeedUrl, cellAddrs);
CellFeed batchRequest = new CellFeed();
for (CellAddress cellAddr : cellAddrs) {
URL entryUrl = new URL(targetFeedUrl.toString() + "/" + cellAddr.idString);
CellEntry batchEntry = new CellEntry(cellAddr.row, cellAddr.col, cellAddr.idString);
String inputValue = cellEntries.get(cellAddr.idString).getCell().getInputValue();
batchEntry.changeInputValueLocal(inputValue);
batchEntry.setId(String.format("%s/%s", targetFeedUrl.toString(), cellAddr.idString));
System.out.println(targetFeedUrl.toString()+": "+cellAddr.idString+" "+ inputValue);
BatchUtils.setBatchId(batchEntry, cellAddr.idString);
BatchUtils.setBatchOperationType(batchEntry, BatchOperationType.UPDATE);
batchRequest.getEntries().add(batchEntry);
}
spreadsheetService.setHeader("If-Match", "*");
// Submit the update
Link batchLink = cellFeed.getLink(ILink.Rel.FEED_BATCH, ILink.Type.ATOM);
CellFeed batchResponse = spreadsheetService.batch(new URL(batchLink.getHref()), batchRequest);
boolean isSuccess = true;
for (CellEntry entry1 : batchResponse.getEntries()) {
String batchId = BatchUtils.getBatchId(entry);
if (!BatchUtils.isSuccess(entry1)) {
isSuccess = false;
BatchStatus status = BatchUtils.getBatchStatus(entry);
}
}
spreadsheetService.setHeader("If-Match", null);
Batch copy:
What is the fastest way to update a google spreadsheet with a lot of data through the spreadsheet api?
There is a Bug with cell references such as $A5.
They will not write to the spreadsheet. While both A5 and $A$5 work, references with just one $ in cause a problem. I forget the fine detail.

cannot preserve space between runs

i want to generate a word document
as an input i have this string "open packaging conventions" and each word will have a different style
the result should be open packaging conventions
WordprocessingDocument document = WordprocessingDocument.Create(
#"C:\test PFE.docx",
WordprocessingDocumentType.Document
);
MainDocumentPart mainDocumentPart = document.AddMainDocumentPart();
mainDocumentPart.Document = new Document();
mainDocumentPart.Document.AddNamespaceDeclaration("ve", "http://schemas.openxmlformats.org/markup-compatibility/2006");
mainDocumentPart.Document.AddNamespaceDeclaration("o", "urn:schemas-microsoft-com:office:office");
mainDocumentPart.Document.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
mainDocumentPart.Document.AddNamespaceDeclaration("m", "http://schemas.openxmlformats.org/officeDocument/2006/math");
mainDocumentPart.Document.AddNamespaceDeclaration("v", "urn:schemas-microsoft-com:vml");
mainDocumentPart.Document.AddNamespaceDeclaration("wp", "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing");
mainDocumentPart.Document.AddNamespaceDeclaration("w10", "urn:schemas-microsoft-com:office:word");
mainDocumentPart.Document.AddNamespaceDeclaration("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
mainDocumentPart.Document.AddNamespaceDeclaration("wne", "http://schemas.microsoft.com/office/word/2006/wordml");
Body documentBody = new Body();
mainDocumentPart.Document.Append(documentBody);
StyleDefinitionsPart styleDefinitionsPart =
mainDocumentPart.AddNewPart<StyleDefinitionsPart>();
FileStream stylesTemplate =
new FileStream("styles.xml", FileMode.Open, FileAccess.Read);
styleDefinitionsPart.FeedData(stylesTemplate);
styleDefinitionsPart.Styles.Save();
#region Titre du document
Paragraph titleParagraphe = new Paragraph() { RsidParagraphAddition = "00AF4948", RsidParagraphProperties = "00625634", RsidRunAdditionDefault = "00625634" }; ;
Run run = new Run();
RunProperties rpr = new RunProperties();
RunStyle rstylr = new RunStyle { Val = "style1" };
run.Append(rpr);
Text t = new Text("open");
run.Append(t);
titleParagraphe.Append(run);
run = new Run();
rpr = new RunProperties();
rstylr = new RunStyle { Val = "style2" };
run.Append(rpr);
t = new Text("packaging")
{
Space = new DocumentFormat.OpenXml.EnumValue<DocumentFormat.OpenXml.SpaceProcessingModeValues> { InnerText = "preserve" }
};
run.Append(t);
titleParagraphe.Append(run);
run = new Run();
rpr = new RunProperties();
rstylr = new RunStyle { Val = "style1" };
run.Append(rpr);
t = new Text("conventions")
{
Space = new DocumentFormat.OpenXml.EnumValue<DocumentFormat.OpenXml.SpaceProcessingModeValues> { InnerText = "preserve" }
};
run.Append(t);
titleParagraphe.Append(run);
documentBody.Append(titleParagraphe);
document.MainDocumentPart.Document.Save();
document.Dispose();
and the result is open*packaging*conventions without space between words
can some one help me please?!
You're on good way by handling the Space property, but you need to do it like this:
t = new Text()
{
Text = "your text with spaces ",
Space = SpaceProcessingModeValues.Preserve
};
Here is another way to set the attribute Space that can be used to specify SpaceProcessingMode.
t = new Text("This is some text");
t.Space = SpaceProcessingModeValues.Preserve;
The default of the attribute is SpaceProcessingModeValues.Default.
From API Documentation:
<w:r>
<w:t> significant whitespace </w:t>
</w:r>
Although there are three spaces on each side of the text content in the run, that whitespace has not been specifically marked as significant, therefore it is subject to the space preservation rules currently specified in that run's scope. end example]
The possible values for this attribute are defined by ยง2.10 of the XML 1.0 specification.

Resources