poi-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Joseph Favero" <...@obsidiansoln.com>
Subject Merge Field Questions
Date Sun, 22 Jan 2006 00:09:59 GMT
I have been able to substitute values into a Word Document where Merge
Fields are Defined
Had to write a few routines in POI to make this  happen.  Namely in the
Range class, I
added a delete() routine and in the CHPBinTable, PAPBinTable and
I had to rewrite the adjustToDelete() to make it remove nodes cleanly.
I can now delete the MergeField Text and insert my own by using the
I am having a problem though with Extra data showing up at the end of the
document.  Not sure
where it is coming from.  Is there something else to adjust when deleting
When I delete Text I do:
1.  Remove the text from the TextTable
2.  Adjust/delete the CHPBinTable
3.  Adjust/delete the PAPBinTable
4.  Adjust/delete the SectionTable
5.  Adjust the length in the Range Class.
I am attaching some code to illustrate my though pattern.
1.  I first Read the HPWFDocument
2.  I parse through the PlexOfCps to find my MergeFields and also find the
character positions
3.  I then delete the characters
4.  I then substite my Data in
This Routine gets the Merge Fields by going through the PlexOfCps
Merge Field have a field type of 59 // per the Microsoft spec
 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,
     String fieldName =
Of("\\*")-2 <file://*%22)-2/> ));
     MergeField mf = new MergeField();
     GenericPropertyNode temp1 =  plc.getProperty(x+1);
     FieldDescriptor temp2 = new FieldDescriptor(temp1.getBytes());
     if (temp2.getFieldBoundaryType() == FieldDescriptor.FIELD_SEPARATOR) {
     } else {
     mergedFields.put(fieldName, mf);
   if (fld.getFieldBoundaryType() == FieldDescriptor.FIELD_SEPARATOR) {
    System.out.println("Node Start: " + node.getStart());
    System.out.println ("Node End: " + node.getEnd());
  Set set = mergedFields.keySet();
  return (String[])set.toArray(new String[0]);
This routine is what I use to get rid of the Merge Field Data and
add my own
 public void generate() {
  CHPBinTable cpt = doc.getCharacterTable();
  List cpl = cpt.getTextRuns();
  // 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: " +
    // Need to find the character run that has this data
    CHPBinTable cpt1 = doc.getCharacterTable();
    List cpl1 = cpt1.getTextRuns();
    for (int i=(cpl1.size()-1); i>=0; i--) {
     CHPX chpx = (CHPX)cpl1.get(i);
     if (mf.getStart() < chpx.getEnd() && mf.getStart() >= chpx.getStart())
      Range r = doc.getRange().getCharacterRun(i);
      // Delete The Merge Text
      r.delete(i, mf.getStart(), (mf.getEnd()-mf.getStart()));
      // Put In the New Text
      r = doc.getRange().getCharacterRun(i);
In order to get ther.delete to work, I had to add it into the Range Class
In the Range Class the code looks like this
 public void delete(int listIndex, int offset, int length)
  TextPiece tp = (TextPiece)_text.get(_textEnd-1);
  StringBuffer sb = (StringBuffer)tp.getStringBuffer();
  sb.delete(offset, (offset+length));
  _doc.getCharacterTable().adjustForDelete(_charEnd-1, offset, length);
  _doc.getParagraphTable().adjustForDelete(_parEnd-1, offset, length);
  _doc.getSectionTable().adjustForDelete(_sectionEnd-1, offset, length);
In the CHPBinTable, PAPBinTable and SectionTable, I updated adjustForDelete
to actually remove nodes no longer needed
The question is ... why do I have extra data at the End??
Thanx Joe

 <http://www.obsidiansoln.com/> 	 rock-solid affordable business

Joseph Favero
President 	Obsidian Solutions, Inc.
7968 South Wabash Court
Centennial, CO 80112 	
mobile: 	303-741-4893

 <https://www.plaxo.com/add_me?u=51539666147&v0=117161&k0=12342058> Add me
to your address book...	

View raw message