Using docx4j to bold specify word in a paragrah - java

I try to generate a simple text like this by Java into docx document
This is **bold** test
I search the online this part of the code will be the close one, however it bolds the whole line, not a specific word
ObjectFactory factory = Context.getWmlObjectFactory();
P p = factory.createP();
R r = factory.createR();
Text text = factory.createText();
RPr rpr = factory.createRPr();
text.setValue("This is bold test");
BooleanDefaultTrue boldTrue = new BooleanDefaultTrue();
boldTrue.setVal(Boolean.TRUE);
rpr.setB(boldTrue);
r.getContent().add(text);
p.getContent().add(r);
r.setRPr(this.rpr);
mainDocumentPart.getContent().add(p);
This will bold all the paragraph, however I just want that word "bold" into bold, and keep remain unbold.
How can I fix this?

You can use the docx4j webapp or Word Helper AddIn to generate the code you need from a suitable sample Word docx.
In this case:
// Create object for p
P p = wmlObjectFactory.createP();
// Create object for r
R r = wmlObjectFactory.createR();
p.getContent().add( r);
// Create object for t (wrapped in JAXBElement)
Text text = wmlObjectFactory.createText();
JAXBElement<org.docx4j.wml.Text> textWrapped = wmlObjectFactory.createRT(text);
r.getContent().add( textWrapped);
text.setValue( "This is ");
text.setSpace( "preserve");
// Create object for r
R r2 = wmlObjectFactory.createR();
p.getContent().add( r2);
// Create object for rPr
RPr rpr = wmlObjectFactory.createRPr();
r2.setRPr(rpr);
// Create object for b
BooleanDefaultTrue booleandefaulttrue = wmlObjectFactory.createBooleanDefaultTrue();
rpr.setB(booleandefaulttrue);
// Create object for bCs
BooleanDefaultTrue booleandefaulttrue2 = wmlObjectFactory.createBooleanDefaultTrue();
rpr.setBCs(booleandefaulttrue2);
// Create object for t (wrapped in JAXBElement)
Text text2 = wmlObjectFactory.createText();
JAXBElement<org.docx4j.wml.Text> textWrapped2 = wmlObjectFactory.createRT(text2);
r2.getContent().add( textWrapped2);
text2.setValue( "bold");
// Create object for r
R r3 = wmlObjectFactory.createR();
p.getContent().add( r3);
// Create object for t (wrapped in JAXBElement)
Text text3 = wmlObjectFactory.createText();
JAXBElement<org.docx4j.wml.Text> textWrapped3 = wmlObjectFactory.createRT(text3);
r3.getContent().add( textWrapped3);
text3.setValue( " test");
text3.setSpace( "preserve");
Then your mainDocumentPart.getContent().add(p);

Related

Accessing a COSArray for PDF fields with Apache PDFBox

I'm trying to access all form fields in a PDF file - so I can use code to fill them in - and this is as far as I've gotten:
PDDocumentCatalog pdCatalog = pdf.getDocumentCatalog();
PDAcroForm pdAcroForm = pdCatalog.getAcroForm();
List<PDField> fieldList = pdAcroForm.getFields(); // fieldList.size() = 1
PDField field = fieldList.get(0);
COSDictionary dictionary = field.getCOSObject();
System.out.println("dictionary size = " + dictionary.size());
// my attempt to iterate through fields
for ( Map.Entry<COSName,COSBase> entry : dictionary.entrySet() )
{
COSName key = entry.getKey();
COSBase val = entry.getValue();
if ( val instanceof COSArray )
{
System.out.println("COSArray size = " + ((COSArray)val).size());
}
System.out.println("key = " + key);
System.out.println("val = " + val);
}
which gives an output of:
dictionary size = 3
COSArray size = 2
key = COSName{Kids}
val = COSArray{[COSObject{110, 0}, COSObject{108, 0}]}
key = COSName{T}
val = COSString{form1[0]}
key = COSName{V}
val = COSString{}
Does anyone know how I can access the two COSObjects in the COSArray? I also don't know what the notation COSObject{x, y} means, and can't find any documentation on this. If those are dictionary or array values elements, I also want to know how to access those.
You get the object with get(index) to get the COSObject (an indirect reference) or getObject(index) to get the dereferenced object referenced by the COSObject.
COSObject{110, 0} is the object number and the generation number (usually 0). Open your PDF file with NOTEPAD++ and look for "110 0 obj" to find it, or "110 0 R" to see who references this object.

Read acrofields with variable page size within document with iText

I am using iText to add and read acrofields. But it runs into issue where page size within document is variable.
So for eg. Pdf document with 3 pages -> letter, legal , letter
Its unable to get all acrofields. But if all pages legal or all pages letter,works perfectly
Here is code which i use to read the acrofields.
String pdf = "D:\\1350211.pdf";
PdfReader reader = new PdfReader( pdf );
AcroFields fields = reader.getAcroFields();
Set<String> fldNames = fields.getFields().keySet();
List<AcrofieldModel> lists = new ArrayList<>();
for (String fldName : fldNames) {
List<FieldPosition> position = fields.getFieldPositions(fldName);
float lowerLeftX = position.get(0).position.getLeft();
float lowerLeftY = position.get(0).position.getBottom();
float upperRightX = position.get(0).position.getRight();
float upperRightY = position.get(0).position.getTop();
float fieldLength = Math.abs(upperRightX-lowerLeftX);
AcrofieldModel acrofieldModel = new AcrofieldModel(fldName, fields.getField( fldName ), "(X:"+lowerLeftX + " , Y:"+lowerLeftY +") ", fieldLength);
lists.add(acrofieldModel);
}
return lists;

Show line on map which connects points - receiving an empty map

I want to plot a line which connects 2 points on a map.
The code I am using:
public class Quickstart {
public static void main(String[] args) throws Exception {
// display a data store file chooser dialog for shapefiles
File file = JFileDataStoreChooser.showOpenFile("shp", null);
if (file == null) {
return;
}
FileDataStore store = FileDataStoreFinder.getDataStore(file);
SimpleFeatureSource featureSource = store.getFeatureSource();
GeometryFactory gf = JTSFactoryFinder.getGeometryFactory();
// ask for current and destination positions
double latitude, longitude, latitudeDest, longitudeDest;
Scanner reader = new Scanner(System.in);
reader.useLocale(Locale.US);
System.out.println("Enter reference longitude and latitude:\n");
longitude = reader.nextDouble();
latitude = reader.nextDouble();
System.out.println("Enter destination longitude and latitude:\n");
longitudeDest = reader.nextDouble();
latitudeDest = reader.nextDouble();
reader.close();
final String EPSG4326 = "GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\"," +
"\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\", " +
"0.01745329251994328,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4326\"]]";
CoordinateReferenceSystem crs = CRS.parseWKT(EPSG4326);
Point start = gf.createPoint(new Coordinate(longitude, latitude));
Point end = gf.createPoint(new Coordinate(longitudeDest, latitudeDest));
GeodeticCalculator gc = new GeodeticCalculator(crs);
gc.setStartingPosition(JTS.toDirectPosition(start.getCoordinate(), crs));
gc.setDestinationPosition(JTS.toDirectPosition(end.getCoordinate(), crs));
// Calculate distance between points
double distance = gc.getOrthodromicDistance();
int totalmeters = (int) distance;
int km = totalmeters / 1000;
int meters = totalmeters - (km * 1000);
float remaining_cm = (float) (distance - totalmeters) * 10000;
remaining_cm = Math.round(remaining_cm);
float cm = remaining_cm / 100;
System.out.println("Distance = " + km + "km " + meters + "m " + cm + "cm");
SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
builder.setName("TwoDistancesType");
builder.setCRS(DefaultGeographicCRS.WGS84);
builder.add("location", Point.class);
// build the type
final SimpleFeatureType TYPE = builder.buildFeatureType();
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
featureBuilder.add(start);
//featureBuilder.add(end);
SimpleFeature feature = featureBuilder.buildFeature(null);
DefaultFeatureCollection featureCollection = new DefaultFeatureCollection("internal", TYPE);
featureCollection.add(feature);
Style style = SLD.createSimpleStyle(TYPE, Color.red);
Layer layer = new FeatureLayer(featureCollection, style);
// Create a map content and add our shapefile to it
MapContent map = new MapContent();
map.setTitle("TEST");
map.addLayer(layer);
// Now display the map
JMapFrame.showMap(map);
}
}
I have 2 problems:
1) I can't add a second feature to featureBuilder.It doesn't allow it.It shows Can handle 1 attributes only, index is 1.
So, how can I plot a line then?
2) With the above code, I am receiving:
org.geotools.renderer.lite.StreamingRenderer fireErrorEvent SEVERE: The scale denominator must be positive
java.lang.IllegalArgumentException: The scale denominator must be positive
------- UPDATE ------------------------
After the solution that #Michael gave for the first question , now I no longer receive the error regarding the denominator, but I am receiving an empty map (white space).
----- UPDATE according to #iant suggestion ----------------
So, I tried this.Created a coordinates which holds the coordinates of the points (start and end) ,then created a linestring with those coordinates and added it to featurebuilder.
SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
builder.setName("TwoDistancesType");
builder.setCRS(DefaultGeographicCRS.WGS84);
builder.add("line", LineString.class); //added a linestring class
final SimpleFeatureType TYPE = builder.buildFeatureType();
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
Coordinate[] coordinates = {start.getCoordinate(), end.getCoordinate()};
LineString line = gf.createLineString(coordinates);
featureBuilder.add(line);
and even though I am loading a map (countries.shp) it shows me an empty white space with a red line.
------ SOLUTION -------------
Ok, so the solution is (thanks to #iants comments):
Style style = SLD.createLineStyle(Color.red, 2.0f);
Layer layer = new FeatureLayer(featureCollection, style);
// Create style for the file
Style shpStyle = SLD.createSimpleStyle(TYPE, Color.blue);
Layer shpLayer = new FeatureLayer(featureSource, shpStyle);
// Create a map content and add our shapefile to it
MapContent map = new MapContent();
map.setTitle("TEST");
map.addLayer(layer);
map.addLayer(shpLayer);
and now you have a red line on a blue map!
You need to create a LineString from your points and then store that in your feature.
You should then get a correct scale but you might want to add some other data such as a coast line to the map first. The quick start tutorial can show you how to do that.
Disclaimer: I've never used geotools.
Looking at the source code of SimpleFeatureBuilder, add calls set which throws that error if:
if(index >= values.length)
throw new ArrayIndexOutOfBoundsException("Can handle "
+ values.length + " attributes only, index is " + index);
values is populated here:
values = new Object[featureType.getAttributeCount()];
so it's obvious that that problem is because your Type only has one property. Change it so it has two:
SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
builder.setName("TwoDistancesType");
builder.setCRS(DefaultGeographicCRS.WGS84);
builder.add("start", Point.class);
builder.add("end", Point.class);

How to read word document and get parts of it with all styles using docx4j

I am using docx4j to deal with word document formatting. I have one word document which is divided in number of tables. I want to read all the tables and if I find some keywords then I want to take those contents to another word document with all the formatting. My word document is as follow.
Like from above I want to take content which is below Some Title. Here my keyword is Sample Text. So whenever Sample Text gets repeated, content needs to be fetched to new word document.
I am using following code.
MainDocumentPart mainDocumentPart = null;
WordprocessingMLPackage docxFile = WordprocessingMLPackage.load(new File(fileName));
mainDocumentPart = docxFile.getMainDocumentPart();
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
ClassFinder finder = new ClassFinder(Tbl.class);
new TraversalUtil(mainDocumentPart.getContent(), finder);
Tbl tbl = null;
int noTbls = 0;
int noRows = 0;
int noCells = 0;
int noParas = 0;
int noTexts = 0;
for (Object table : finder.results) {
noTbls++;
tbl = (Tbl) table;
// Get all the Rows in the table
List<Object> allRows = DocxUtility.getDocxUtility()
.getAllElementFromObject(tbl, Tr.class);
for (Object row : allRows) {
Tr tr = (Tr) row;
noRows++;
// Get all the Cells in the Row
List<Object> allCells = DocxUtility.getDocxUtility()
.getAllElementFromObject(tr, Tc.class);
toCell:
for (Object cell : allCells) {
Tc tc = (Tc) cell;
noCells++;
// Get all the Paragraph's in the Cell
List<Object> allParas = DocxUtility.getDocxUtility()
.getAllElementFromObject(tc, P.class);
for (Object para : allParas) {
P p = (P) para;
noParas++;
// Get all the Run's in the Paragraph
List<Object> allRuns = DocxUtility.getDocxUtility()
.getAllElementFromObject(p, R.class);
for (Object run : allRuns) {
R r = (R) run;
// Get the Text in the Run
List<Object> allText = DocxUtility.getDocxUtility()
.getAllElementFromObject(r, Text.class);
for (Object text : allText) {
noTexts++;
Text txt = (Text) text;
}
System.out.println("No of Text in Para No: " + noParas + "are: " + noTexts);
}
}
System.out.println("No of Paras in Cell No: " + noCells + "are: " + noParas);
}
System.out.println("No of Cells in Row No: " + noRows + "are: " + noCells);
}
System.out.println("No of Rows in Table No: " + noTbls + "are: " + noRows);
}
System.out.println("Total no of Tables: " + noTbls );
Assuming your text is in a single run (ie not split across runs), then you can search for it via XPath. Or you can manually traverse using TraversalUtil. See docx4j's Getting Started for more info.
So finding your stuff is pretty easy. Copying the formatting it uses, and any rels in it, is in the general case, complicated. See my post http://www.docx4java.org/blog/2010/11/merging-word-documents/ for more on the issues involved.

OWL Class Expression for Data Property

In my ontology, I have an individual that has this data property
hasName "somaName"^^string,
however, when i'm building a class expression and sending to the reasoner for get the instances, I'm getting an empty set with the following query,
OWLClassExpression x = schema.getFactory().getOWLDataHasValue(schema.getDataProperty("hasName"), schema.getFactory().getOWLLiteral("somaName"));
System.out.println(reasoner.getInstances(x, true));
the getDataProperty is just a small method:
public OWLDataProperty getDataProperty(String dataProperty){
return factory.getOWLDataProperty("#"+dataProperty,pm);
}
The following code snippet works, compare it to your code to see what's different. You should use a reasoner that support this type of construct (Hermit does).
//Initiate everything
OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
String base = "http://www.example.org/";
OWLOntology ontology = manager.createOntology(IRI.create(base + "ontology.owl"));
OWLDataFactory factory = manager.getOWLDataFactory();
//Add the stuff to the ontology
OWLDataProperty hasName = factory.getOWLDataProperty(IRI.create(base + "hasName"));
OWLNamedIndividual john = factory.getOWLNamedIndividual(IRI.create(base + "john"));
OWLLiteral lit = factory.getOWLLiteral("John");
OWLDataPropertyAssertionAxiom ax =
factory.getOWLDataPropertyAssertionAxiom(hasName, john, lit);
AddAxiom addAx = new AddAxiom(ontology, ax);
manager.applyChange(addAx);
//Init of the reasoner
//I use Hermit because it supports the construct of interest
OWLReasonerFactory reasonerFactory = new Reasoner.ReasonerFactory();
OWLReasoner reasoner = reasonerFactory.createReasoner(ontology);
reasoner.precomputeInferences();
//Prepare the expression for the query
OWLDataProperty p = factory.getOWLDataProperty(IRI.create(base + "hasName"));
OWLClassExpression ex =
factory.getOWLDataHasValue(p, factory.getOWLLiteral("John"));
//Print out the results, John is inside
Set<OWLNamedIndividual> result = reasoner.getInstances(ex, true).getFlattened();
for (OWLNamedIndividual owlNamedIndividual : result) {
System.out.println(owlNamedIndividual);
}

Categories