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
SectionTable,
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
insertAfter.
 
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
text??
 
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,
node.getEnd());
     String fieldName =
mergeField.substring((mergeField.indexOf("MERGEFIELD")+12),(mergeField.index
Of("\\*")-2 <file://*%22)-2/> ));
     MergeField mf = new MergeField();
     mf.setFieldName(fieldName);
     mf.setStart(node.getStart());
     GenericPropertyNode temp1 =  plc.getProperty(x+1);
     FieldDescriptor temp2 = new FieldDescriptor(temp1.getBytes());
     if (temp2.getFieldBoundaryType() == FieldDescriptor.FIELD_SEPARATOR) {
      mf.setEnd(temp1.getEnd());
     } else {
      mf.setEnd(node.getEnd());
     }
     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: " +
mf.getValue());
    
    // 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);
      r.insertAfter(mf.getValue());
     }
    }
   }
  }
 }
 
********************
 
In order to get ther.delete to work, I had to add it into the Range Class
(attached)
In the Range Class the code looks like this
 
*********************
 
 public void delete(int listIndex, int offset, int length)
 {
  initAll();
  
  TextPiece tp = (TextPiece)_text.get(_textEnd-1);
  StringBuffer sb = (StringBuffer)tp.getStringBuffer();
  sb.delete(offset, (offset+length));
  _doc.getTextTable().adjustForDelete(_textEnd-1,length);
  _doc.getCharacterTable().adjustForDelete(_charEnd-1, offset, length);
  _doc.getParagraphTable().adjustForDelete(_parEnd-1, offset, length);
  _doc.getSectionTable().adjustForDelete(_sectionEnd-1, offset, length);
  adjustForDelete(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
software	
	

Joseph Favero
President 	Obsidian Solutions, Inc.
7968 South Wabash Court
<http://maps.yahoo.com/py/maps.py?Pyt=Tmap&addr=7968+South+Wabash+Court&csz=
Centennial%2C+CO+80112&country=us> 
Centennial, CO 80112 	
joe@obsidiansoln.com 	
tel: 
mobile: 	303-741-4893
303-522-4663 	
	

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

Mime
View raw message