I have gotten alot
of request for doing the same thing I have been trying to do for over a
month.
I simply want to
read in a Microsoft Word 97 document and then read in the Merged
Fields,
substitute data in
for the merged fields and generate a new document. I believe this is a
fairly
reusable use case,
however with POI, I have yet to make it happen.
I know there is the
promise of a new release for HPWF coming, however there is no Dates or
even
documents on what
this means. If there are some MS Word gurus out there, I would like to
share
where I am and see
if we can beat up this old horse:
I have written a
routine that gets a list of merged fields from the HPWF document ... here it
is:
public
String[] getMergeFields() {
mergedFields = new Hashtable();
PlexOfCps plc = doc.getPlexOfCps();
for (int x = 0; x < plc.length(); x++)
{
GenericPropertyNode node = plc.getProperty(x);
FieldDescriptor fld = new FieldDescriptor(node.getBytes());
if (fld.getFieldBoundaryType() == FieldDescriptor.FIELD_BEGIN_MARK) {
if (fld.getFieldType() == 59) {
String mergeField = doc.getRange().text().substring(node.getStart()+1, node.getEnd());
String fieldName = mergeField.substring((mergeField.indexOf("MERGEFIELD")+12),(mergeField.indexOf("\\*")-2));
MergeField mf = new MergeField();
mf.setFieldName(fieldName);
mf.setStart(node.getStart());
mf.setEnd(node.getEnd());
mergedFields.put(fieldName, mf);
}
}
}
Set set = mergedFields.keySet();
return (String[])set.toArray(new String[0]);
}
mergedFields = new Hashtable();
PlexOfCps plc = doc.getPlexOfCps();
for (int x = 0; x < plc.length(); x++)
{
GenericPropertyNode node = plc.getProperty(x);
FieldDescriptor fld = new FieldDescriptor(node.getBytes());
if (fld.getFieldBoundaryType() == FieldDescriptor.FIELD_BEGIN_MARK) {
if (fld.getFieldType() == 59) {
String mergeField = doc.getRange().text().substring(node.getStart()+1, node.getEnd());
String fieldName = mergeField.substring((mergeField.indexOf("MERGEFIELD")+12),(mergeField.indexOf("\\*")-2));
MergeField mf = new MergeField();
mf.setFieldName(fieldName);
mf.setStart(node.getStart());
mf.setEnd(node.getEnd());
mergedFields.put(fieldName, mf);
}
}
}
Set set = mergedFields.keySet();
return (String[])set.toArray(new String[0]);
}
This is looking at
the PlecOfCps and finding the merged fields and returning the strings that
represent the field Name.
MergeField Class is
where I am storing this Info
I then pass in my
new data that I want to substitute for the Merged Fields.
My guess is that I
need to delete the data in the TextPieces them insert the new
data,
When I do this, the
new file generated is corrupted and unreadable.
public void
generate() {
// Run the Merger Utility
Collection c = mergedFields.values();
Iterator iter = c.iterator();
while (iter.hasNext()) {
MergeField mf = (MergeField)iter.next();
if (mf.isUpdate()) {
System.out.println("Updating: " + mf.getFieldName() + " With: " + mf.getValue());
System.out.println("MF Start: " + mf.getStart());
System.out.println("MF End: " + mf.getEnd());
TextPieceTable tpt = doc.getTextTable();
List tpl = tpt.getTextPieces();
for (int i=0; i<tpl.size(); i++) {
TextPiece tp = (TextPiece) tpl.get(i);
System.out.println ("CP: " + tp.getCP());
System.out.println ("Start: " + tp.getStart());
System.out.println ("End: " + tp.getEnd());
System.out.println ("Length: " + tp.characterLength());
System.out.println ("SB: " + tp.substring(mf.getStart(), mf.getEnd()));
//tp.adjustForDelete(0, 0);
tp.adjustForDelete(mf.getStart(), (mf.getEnd()-mf.getStart()));
// Adjust Character Positions
CHPBinTable cpt = doc.getCharacterTable();
//cpt.adjustForDelete(tp.getCP(), mf.getStart(), (mf.getEnd()-mf.getStart()));
}
// Run the Merger Utility
Collection c = mergedFields.values();
Iterator iter = c.iterator();
while (iter.hasNext()) {
MergeField mf = (MergeField)iter.next();
if (mf.isUpdate()) {
System.out.println("Updating: " + mf.getFieldName() + " With: " + mf.getValue());
System.out.println("MF Start: " + mf.getStart());
System.out.println("MF End: " + mf.getEnd());
TextPieceTable tpt = doc.getTextTable();
List tpl = tpt.getTextPieces();
for (int i=0; i<tpl.size(); i++) {
TextPiece tp = (TextPiece) tpl.get(i);
System.out.println ("CP: " + tp.getCP());
System.out.println ("Start: " + tp.getStart());
System.out.println ("End: " + tp.getEnd());
System.out.println ("Length: " + tp.characterLength());
System.out.println ("SB: " + tp.substring(mf.getStart(), mf.getEnd()));
//tp.adjustForDelete(0, 0);
tp.adjustForDelete(mf.getStart(), (mf.getEnd()-mf.getStart()));
// Adjust Character Positions
CHPBinTable cpt = doc.getCharacterTable();
//cpt.adjustForDelete(tp.getCP(), mf.getStart(), (mf.getEnd()-mf.getStart()));
}
}
}
}
}
}
I had to write a
routine in the TextPiece to implement adjustForDelete()
Here it
is
public
void adjustForDelete(int start, int length)
{
_buf = new StringBuffer(substring(0,start) + substring(start+length, characterLength()));
super.adjustForDelete(start,length);
{
_buf = new StringBuffer(substring(0,start) + substring(start+length, characterLength()));
super.adjustForDelete(start,length);
}
I may be way off,
there may be a better way of doing Merge Fields, however if anyone can help here
... it would benefit
alot of
people. I have gotten many emails of people trying to figure out the same
thing.
Thanx
Joe
| ||||||||||||||
| ||||||||||||||
