Restart numeration in multiple tables with docx4j - docx4j

I need to create a .docx file using docx4j with many tables based on a template.
Tables must have rows with automatic numeration.
After copying table from template numeration continues in consecutive tables, like this:
table 1
List item
List item
table 2
List item
List item
How can I restart numeration for every table to obtain this:
table 1
List item
List item
table 2
List item
List item
I found that there exists NumberingDefinitionPart.restart() method that could be helpful but how can I apply it on each table?
Could you give example with java code?

For each table after the first, you need to create/add a list level override to the numbering definitions part, then use that in your numPr (ie in your "list item").
The method you mentioned does this:
/**
* For the given list numId, restart the numbering on the specified
* level at value val. This is done by creating a new list (ie <w:num>)
* which uses the existing w:abstractNum.
* #param numId
* #param ilvl
* #param val
* #return
*/
public long restart(long numId, long ilvl, long val)
throws InvalidOperationException {
// Find the abstractNumId
// (Ensure maps are initialised)
if (em == null ) {
getEmulator();
}
ListNumberingDefinition existingLnd = instanceListDefinitions.get( Long.toString(numId) );
if (existingLnd==null) {
throw new InvalidOperationException("List " + numId + " does not exist");
}
BigInteger abstractNumIdVal = existingLnd.getNumNode().getAbstractNumId().getVal();
// Generate the new <w:num
long newNumId = instanceListDefinitions.size() + 1;
org.docx4j.wml.ObjectFactory factory = Context.getWmlObjectFactory();
Num newNum = factory.createNumberingNum();
newNum.setNumId( BigInteger.valueOf(newNumId) );
AbstractNumId abstractNumId = factory.createNumberingNumAbstractNumId();
abstractNumId.setVal(abstractNumIdVal);
newNum.setAbstractNumId(abstractNumId);
LvlOverride lvlOverride = factory.createNumberingNumLvlOverride();
lvlOverride.setIlvl(BigInteger.valueOf(ilvl));
newNum.getLvlOverride().add(lvlOverride);
StartOverride start = factory.createNumberingNumLvlOverrideStartOverride();
start.setVal(BigInteger.valueOf(val));
lvlOverride.setStartOverride(start);
// Add it to the jaxb object and our hashmap
((Numbering)getJaxbElement()).getNum().add(newNum);
ListNumberingDefinition listDef
= new ListNumberingDefinition(newNum, abstractListDefinitions);
instanceListDefinitions.put(listDef.getListNumberId(), listDef);
// Return the new numId
return newNumId;
}
https://github.com/plutext/docx4j/blob/master/src/samples/docx4j/org/docx4j/samples/NumberingRestart.java is an example of using it.
In your numPr element in your w:p "list item":
<w:pPr>
<w:numPr>
<w:ilvl w:val="0"/>
<w:numId w:val="1"/>
</w:numPr>
</w:pPr>
set level (ilvl) to the level you used in the method; set numid to the value the method returns.
As noted in the sample, after the first paragraph using newNumId, it doesn't matter whether subsequent paragraphs use that or the original numId.

Related

TYPO3: Get the values in fluid from inline elements

I managed to create an own inline content element (on tt_content table) but when i try to get the values on the frontend via fluid, i get nothing.
I debugged the {data} variable and on the column that my data are saved, there is an integer. I suppose it reads the number of the content elements which were created on the foreign table (accordion). How can i get those values?
At this point the {data} variables reads the tt_content table and the column that has the integer reads the number of content elements on the table accordion.
I suppose no code is necessary. If it is necessary, feel free to comment the part of the code you would like to review.
Best regards
You need to add a DataProcessor to your TypoScript creating the content element, which fetch your accordion records. Example:
tt_content {
yourContentElementName < lib.contentElement
yourContentElementName.templateName = YourContentElementName
yourContentElementName.dataProcessing {
10 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
10 {
if.isTrue.field = fieldInTtContentWithInteger
table = your_accordion_table
pidInList = this
where.field = uid
where.intval = 1
where.dataWrap = field_pointing_to_ttcontent_record = |
as = accordions
}
}
}

Creating a new set from components of an existing set in OPL/CPLEX

I have a set that I have read into my OPL project that looks like this:
S = {<"A","">, <"B","">, <"AB","A">, <"AB","B">, <"C","">, <"ABC","A">,<"ABC","B">, <"ABC","C">, <"ABC","AB">},
where each element <,> is a tuple with two string elements. This set represents parent-child relationships between items of interest.
From this set I need to create a new set:
S' = {<"A",{""}>, <"B",{""}>, <"C",{""}>, <"AB",{"A","B"}>, <"ABC",{"A","B","C","AB"}>},
where each element <,> is a tuple with the first element of each tuple a string and the second element of each tuple a set of strings. My attempt at creating this set is:
tuple child{
string Item;
string Child;
}
{child} Children = ...; //Reads in the set S
tuple dependents{
string Item;
{string} ItemChildren;
}
{dependents} dependentsSet = {<x.Item, y.Child> | x in Children, (y in Children : <x,y> in Children)};
Using the variable names from the above code, the purpose of creating S' is because later in my program I need to create a collection of constraints, one for each Item, and within each constraint I need to index over the ItemChildren. I'm a relative novice with OPL so I know I'm using the syntax incorrectly in the initialization of the dependentsSet variable, but I don't know how to write this statement correctly such that it creates the set I'm looking for.
Can anyone help me understand the statements required to create the set I'm after?
tuple child{
string Item;
string Child;
}
{child} Children
= {<"A","">, <"B","">, <"AB","A">, <"AB","B">, <"C","">, <"ABC","A">,
<"ABC","B">, <"ABC","C">, <"ABC","AB">};
{string} setOfParents={i.Item | i in Children};
{string} setOfChildren={i.Child | i in Children};
tuple dependents{
string Item;
{string} ItemChildren;
}
{string} kids[p in setOfParents]={k | k in setOfChildren : <p,k> in Children};
{dependents} dependentsSet = {<x, kids[x]> | x in setOfParents};
execute
{
writeln(dependentsSet);
}
gives
{<"A" {""}> <"B" {""}> <"AB" {"A" "B"}> <"C" {""}>
<"ABC" {"A" "B" "C" "AB"}>}

SSIS import a Flat File to SQL with the first row as header and last row as a total

I receive Text File that I have to Import to a SQL Table, I have to come with a SSIS because I will received the Flat File every Day , with the First Row as the Customer_ID, then come the invoice details and then the Total of the invoice.
Example :
30303
0000109291700080190432737000005Name of the product
0000210291700080190432737000010Name of the product
0000309291700080190432737000000Name of the product
003 000145
So let me Explain:
First 30303 is the Customer #
Other Rows Invoice Details
00001-> ROWID 092917-> DATE 000801904327->PROD 370->Trans 00010 -> AMOUNT
Name of the product
Last Row
003==>Total rows 000145==>Total of Invoice
Any Clue ?
I would use a Script Component as a source in a Data Flow Task. You can then use C# or VB.net to read the file, e.g., by using System.IO.StreamReader, in any way you wish. You can read a line at a time, store values in variables to write to every row (e.g., the customer number), etc. It's extremely flexible for complex files.
Here is an example script (C#) based on your data:
public override void CreateNewOutputRows()
{
System.IO.StreamReader reader = null;
try
{
bool line1Read = false;
int customerNumber = 0;
reader = new System.IO.StreamReader(Variables.FilePath); // this refers to a package variable that contains the file path
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
if (!line1Read)
{
customerNumber = Convert.ToInt32(line);
line1Read = true;
}
else if (!reader.EndOfStream)
{
Output0Buffer.AddRow();
Output0Buffer.CustomerNumber = customerNumber;
Output0Buffer.RowID = Convert.ToInt32(line.Substring(0, 5));
Output0Buffer.Date = DateTime.ParseExact(line.Substring(5, 6), "MMddyy", System.Globalization.CultureInfo.CurrentCulture);
Output0Buffer.Prod = line.Substring(11, 12);
Output0Buffer.Trans = Convert.ToInt32(line.Substring(23, 3));
Output0Buffer.Amount = Convert.ToInt32(line.Substring(26, 5));
Output0Buffer.ProductName = line.Substring(31);
}
}
}
catch
{
if (reader != null)
{
reader.Close();
reader.Dispose();
}
throw;
}
}
The columns in 'Output 0' of the Script Component are configured as follows:
Name DataType Length
==== ======== ======
CustomerNumber four-byte signed integer [DT_I4]
RowID four-byte signed integer [DT_I4]
Date database date [DT_DBDATE]
Prod string [DT_STR] 12
Trans four-byte signed integer [DT_I4]
Amount four-byte signed integer [DT_I4]
ProductName string [DT_STR] 255
To implement this:
Create a string variable called 'FilePath' with your file path in it for the script to reference.
Create a Data Flow Task.
Add a Script Component to the Data Flow Task - you'll be asked what type it should be, select 'Source'.
Right-click the Script Component, click 'Edit'.
On the 'Script' pane, add the 'FilePath' variable to the 'ReadOnlyVariables' section.
On the 'Inputs and Outputs' pane, expand 'Output 0' and add columns to the 'Output Columns' section as per the above table.
On the 'Script' pane, click 'Edit Script', and then paste my code over the public override void CreateNewOutputRows() method (replacing it).
Your Script Component source is now configured, and you'll be able to use it like any other data source component. To write this data to a SQL Server table, add an OLEDB Destination to the Data Flow Task, and link the Script Component to that, configuring the columns appropriately.

Attributes of tables in VS by coding with C#

I have this table:
Please, don't mind because it's on my native language and it doesn't matter..
Those are all attributes in table but when I go to Visual StudioS and try to use some of this I get this one:
I see all "normal" attributes in VS but where is those FK attributes?
I need them to compare few ones and get values?
I can't use it from name of other tables [dot] attribute etc...
like for example:
I need this: table1.ID == table2.ID
and not this: table1.ID == table1.table2.ID
Where or what is FK attribute in VS that is shown in SQL table ??
public void setParametri(int desID)
{
foreach (desavanje d in DM_Class.dc.desavanje)
if (d.desavanjeID == desID)
{
//THIS FIRST 4 LINES WORKS PERFECTLY
this.naziv_des = d.naziv_des;
this.datum_po = d.datum_pocetka.ToString();
this.datum_zav = d.datum_kraja.ToString();
this.cijena = d.cijena_des;
//foreach (klijenti k in DM_Class.dc.klijenti)
//{
// if(k.klijentID == //WHAT TO PUT HERE TO COMPARE VALUE klijentID from tables klijenti with FK value in table desavanje)
// this.klijent = k.Ime + ' ' + k.Prezime;
//}
//ON THIS LINE I'M GETTING ERROR - Object reference not set to an instance of an object. but why?
//I have data on that field in DB ?
//this.grad = d.mjesto_desavanja.gradovi.naziv_grada.ToString();
//this.mjesto = d.mjesto_desavanja.naziv_objekta;
//this.organizator = d.organizator.Ime + ' ' + d.organizator.Prezime;
//this.tip = d.tip_desavanja.vrsta_des;
this.klijent = d.klijenti.Ime + ' ' + d.klijenti.Prezime;
//this.status = d.status_desavanja.naziv_statusa;
//this.br_gost = d.specifikacija_desavanja.br_osoba;
}
}
If is there other solution to get values for attributes I'm willing to try it without using another foreach loop?
Ok, I managed this.. I've used a linq query to generate data that I need and in that queries I've compared needed ID's and finally get some working stuff.

Selenium: Get unique value?

Just using selenium to fill out some forms for me. I need it to generate a unique value for my username field. How can I do that?
I've got
Command: type
Target: id_of_my_field
Value: username+unique_value ???
You can use javascript to do that:
Value: javascript{'username'+Math.floor(Math.random()*100000)}
This will append a 6 digit random number to your username.
See this SO question and answers for more details and other ways to do this...
My solution which works well for me:
Save the following TEXT as a .js file and add to the Options->Options "Selenium Core Extensions" list...
Selenium.prototype.doTypeRandomName = function(locator)
{
/**
* Sets the value of an input field to a random "name"
* as though you typed it in.
*/
// All locator-strategies are automatically handled by "findElement"
var element = this.page().findElement(locator);
/* The following block generates a random name 8 characters in length */
var allowedChars = "abcdefghiklmnopqrstuvwxyz";
var stringLength = 8;
var randomstring = '';
for (var i=0; i<stringLength; i++) {
var rnum = Math.floor(Math.random() * allowedChars.length);
randomstring += allowedChars.substring(rnum,rnum+1);
}
// Replace the element text with the new text
this.browserbot.replaceText(element, randomstring);
}
Once done, you can simply select the TypeRandomName command in Selenium for each text box where you want a random "name" to be generated.
Steps for a globally reusable solution is as follows
1) Download sideflow.js from Download here
2) Add following lines into it :
Selenium.prototype.doTypeRandomName = function(locator) {
/**
* Sets the value of an input field to a random email id,
* as though you typed it in.
*
* #param locator an element locator
*/
// All locator-strategies are automatically handled by "findElement"
var element = this.page().findElement(locator);
/* The following block generates a random email string */
var allowedChars = "abcdefghiklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
var stringLength = 8;
var randomstring = '';
for (var i=0; i<stringLength; i++) {
var rnum = Math.floor(Math.random() * allowedChars.length);
randomstring += allowedChars.substring(rnum,rnum+1);
}
// Replace the element text with the new text
this.browserbot.replaceText(element, randomstring);
};
3) Save the file
4) Go to Selenium ide -> options -> options ->Selenium Core extensions -> give reference of your file there.
5) Now your randomname function will appear in auto-intellisense and will be as "typerandomname" command category.
6) Sample usage could be (if base url is google.com)
<tr>
<td>open</td>
<td>/</td>
<td></td>
</tr>
<tr>
<td>typerandomname</td>
<td>css=input[class='gbqfif']</td>
<td></td>
</tr>
Hope this helps you
Here is a way to generate unique numbers without using JavaScript in your code: (i used Java)
DateFormat dateFormat = new SimpleDateFormat("ddHHmmss"); /* Here you create object of the class DateFormat, and SPECIFY THE FORMAT (ddHHmmss). (Don`enter code here`t forget to import class Date(ctrl+shift+o if you are using Eclipse)) */
Date date = new Date(); /* Here you create object of the class Date. (Dont forget to import class Date. (Dont forget to import class Date(ctrl+shift+o if you are using Eclipse)) */
String random_number = dateFormat.format(date); /* Assign your current Date(something like 19184123) (ddHHmmSS) to a local variable(it require a String) */
yourWebDriver().findElemnt(By.cssSelector("input#someId")).sendKeys("test"+random_number+"#tester.com"); /* send keys to your input injecting random number */
Such method will give truly unique number that will never repeat itself, because it use your current time...
You can add even further randomness if include mile seconds into DateFormat