You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@poi.apache.org by Brian Rosenberger <BR...@serena.com> on 2011/06/26 17:57:42 UTC

AW: Replacing placeholder to a Table.

Hi,

I am facing the same problem. The insertTable() method correctly adds the table into the body element list (correct position between two paragraphs). But when the document is written, all tables end up at the end of the document.
However tables inserted by ms word remain at their original location.

Cheers
Brian

-----Ursprüngliche Nachricht-----
Von: Mark Beardsley [mailto:markbrdsly@tiscali.co.uk] 
Gesendet: Samstag, 26. Februar 2011 13:22
An: user@poi.apache.org
Betreff: Re: Replacing placeholder to a Table.

Hello again Andre,

I do not know if you are stil working on this problem but I have been a little today and can report no p[rogress at all. It is a trivial task to build a document sequentially; inserting a new paragraph followed by a table followed by another paragraph, etc, but I cannot yet find a way to insert a table between two existing paragraphs; whatever I try, the table simply appears at the end of the document.

I think that the key lies in one of two places - allowing us to directly update either the tables list or the body elements list, both of which are protected and so inaccessible to client code. To date, I have not looked at the source of the XWPF class but suspect that this is the way the
insertTable() and setTable() methods try to work. It would be perfect if we could use the set/insertTable methods to allow us to position a table in the document in it's correct location and I will look to see if this is possible. As always, will be in touch if I make any progress.

Yours

Mark B

--
View this message in context: http://apache-poi.1045710.n5.nabble.com/Replacing-placeholder-to-a-Table-tp3392424p3401338.html
Sent from the POI - User mailing list archive at Nabble.com.



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org


AW: AW: Replacing placeholder to a Table.

Posted by Brian Rosenberger <BR...@serena.com>.
Hi Nick,

meanwhile I've created a small test class that indicates the problem. I have a table between two paragraphs and I simply would like to re-sort those IBodyElements, so that the table is first - followed by two paragraphs.
When I simply try to resort the list or to replace it, I get an UnmodifiableCollection Exception.

Against TAG REL_3_8_BETA3:

package net.brutex.msd2docx;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.xwpf.usermodel.*;

public class Test {
	static String outputfile = "c:/temp/testdoc.docx";

	public static void main(String[] args) {
		try {
			//Create an XWPFDoc and put a table between two
			//paragraphs
			XWPFDocument d = new XWPFDocument();
			XWPFParagraph p1 = d.createParagraph();
			XWPFRun r1= p1.createRun();
			r1.setText("Paragraph 1, Run 1.");
			XWPFTable t1 = d.createTable(4, 3);
			t1.getRow(0).getCell(0).setText("Table 1");
			XWPFParagraph p2 = d.createParagraph();
			XWPFRun r2= p2.createRun();
			r2.setText("Paragraph 2, Run 2.");
			
			//Howto move table t1 to another position, 
			//i.e. above p1 ?
			
			//Just list the IBodyElement List
			List<IBodyElement> list = d.getBodyElements();
			int i=0;
			for ( IBodyElement e : list ) {
				System.out.println(i + ": " + e.getElementType().name());				
				i++;
			}

			d.write(new FileOutputStream(outputfile));
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

Cheers
Brian





Von: Nick Burch [mailto:nick.burch@alfresco.com] 
Gesendet: Montag, 27. Juni 2011 12:38

I think we should be maintaining a list with both paragraphs and tables in it though, with relative ordering preserved. On XWPFDocument there's
 	List<IBodyElement> bodyElements
for example, which is built by doing a child walk and storing the entries in the order they occur

I'd look at extending that to suit your needs

Nick

Re: AW: Replacing placeholder to a Table.

Posted by Jaakov Jalink <hi...@gmail.com>.
Encountered this issue a few hours ago, here is my solution:

	XmlCursor cursor = doc.getDocument().getBody().newCursor();
	cursor.selectPath("./*");
	while (cursor.toNextSelection()) {
		XmlObject o = cursor.getObject();
		if (o instanceof CTP) {
			XWPFParagraph paragraph = new XWPFParagraph((CTP) o, doc);
			for (CTR run : paragraph.getCTP().getRList()) {
				for (CTText text : run.getTList()) {
					if(newText.indexOf("POSITION")>-1){
						newText = newText.replaceAll("POSITION", "");//remove place holder
text
						text.setStringValue(newText);
						
						XWPFTable tableOne = paragraph.getBody().insertNewTbl(c);
					}
				}
			}
		} else if (o instanceof CTTbl) {
			XWPFTable t = new XWPFTable((CTTbl) o, doc);//i don't care about these
right now
		}
	}
	cursor.dispose();

Where POSITION is place holder in for where the table should be
Table is placed right before the paragraph with the placeholder

The trick with insertNewTbl is that the cursor has to come from the document
body, otherwise it returns null (see XWPFDocument source)

Note - ooxml-schemas-1.1.jar required for this to work ( download link
<http://repo1.maven.org/maven2/org/apache/poi/ooxml-schemas/1.1/>  )



--
View this message in context: http://apache-poi.1045710.n5.nabble.com/Replacing-placeholder-to-a-Table-tp3392424p5713654.html
Sent from the POI - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org


Re: AW: Replacing placeholder to a Table.

Posted by Mark Beardsley <ma...@tiscali.co.uk>.
Sorry to say this but you will need to download the source for the project
and create a patch for XWPF yourself so that it handles the insertion of
tables correctly. Remember that POI is not a commercial product and that
everyone that works on it does so as a volunteer. Typically, people develop
areas of the api as they need that specific functionality; it seems as
though you have a pressing need to work with tables and so are the ideal
person to enhance this part.

The problem may not be as simple as it seems. Yesterday, I played around
with some test code and found that the createTable() methods do create a new
table that is added to the bottom of the list of body elements. If a call to
the setTable() method is made, this will move the position of the table in
the body element list but seems to create a second entry; it appears to
leave the original entry at the bottom of the list and then create a second
entry in the correct position. Confusingly however, saving this document
creates xml markup with just a single copy of the table, the one created at
the bottom of the list of body elements and it seems to me that the write
process it doing something a little strange. To confirm this, I created the
new table directly myself and then set it into the document. This did result
in a list of body elements that showed a single entry for the table and in
the correct position. It still, however, resulted in the markup being
created with the table at the end of the document. This is why I suspect
that something is awry with the writing of the markup when the document is
saved, no proof just a suspicion.

I cannot investigate further myself - not clever enough to dig around in the
source code of the api - but this is what I feel you will have to do. Find
out how the list of body elements is processed when the document is saved
and why the position of the table within it is being ignored when a new
table - seemingly, existing tables read in from documents are handled
properly but I have yet to fully confirm this - is created and I think you
will have the answer.



--
View this message in context: http://apache-poi.1045710.n5.nabble.com/Replacing-placeholder-to-a-Table-tp3392424p5712081.html
Sent from the POI - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org


Re: AW: Replacing placeholder to a Table.

Posted by sars84 <sa...@googlemail.com>.
Hi;

I have now the same Problem. i tried this way, but no success.
Did you got another solution for the table or what had you done?
----
XWPFDocument newDoc = new XWPFDocument();
for(IBodyElement element : list){
if(element.getElementType().equals("TABLE"){
XWPFTable tb = newDoc.createTable();
newDoc.setTable(newDoc.getPosOfTable(tb), tableToAdd);
}
} 
---

I need some support, please...
Thanks in advance.
sars



--
View this message in context: http://apache-poi.1045710.n5.nabble.com/Replacing-placeholder-to-a-Table-tp3392424p5712072.html
Sent from the POI - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org


Re: AW: Replacing placeholder to a Table.

Posted by IsadorCJ <is...@gmail.com>.
I have a way of dealing with the "replacement" issue. I have tried serveral
days, but cannot finish the task. (a similar task as the OP had). 
So my approach is create an empty List<IBodyElement> 
so now you read in your templates, according to the templates, construct
paragraphs and tables, and then stuff them into the list with order. 
and then you can use a for loop:
XWPFDocument newDoc = new XWPFDocument();
for(IBodyElement element : list){
if(element.getElementType().equals("PARAGRAPH"){
XWPFParagraph pr = newDoc.createParagraph();
newDoc.setParagraph((XWPFParagraph) element, newDoc.getPosOfParagrah(pr));
}
}
and add your if condition to table.......by doing the same.....

this will do the trick~ i've proven it work. 

but this has a serious problem: if there is a picture in the original
document, it will show as a "broken linked picture" like what you see on
website, and tells you the picture currently cannot be showed. 


--
View this message in context: http://apache-poi.1045710.n5.nabble.com/Replacing-placeholder-to-a-Table-tp3392424p5709992.html
Sent from the POI - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org


Re: AW: Replacing placeholder to a Table.

Posted by primeq <pa...@yahoo.com>.
Nick,

I'm unable to find any more information on what seems to still be inability
to place a new table in a specified location (i.e. not at the bottom of the
document).

Do you know if there have been any changes, or any new advice on how to make
the table go where I want (happens I also want to put it within a
table-cell)
Nick Burch-11 wrote
> 
> On Mon, 27 Jun 2011, Brian Rosenberger wrote:
>> Each element is exposed through a separate list, thus ordering is lost.
> 
> I think we should be maintaining a list with both paragraphs and tables in 
> it though, with relative ordering preserved. On XWPFDocument there's
>  	List<IBodyElement> bodyElements
> for example, which is built by doing a child walk and storing the entries 
> in the order they occur
> 
> I'd look at extending that to suit your needs
> 
> Nick
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@.apache
> For additional commands, e-mail: user-help@.apache
> 


--
View this message in context: http://apache-poi.1045710.n5.nabble.com/Replacing-placeholder-to-a-Table-tp3392424p5600175.html
Sent from the POI - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org


Re: AW: Replacing placeholder to a Table.

Posted by Nick Burch <ni...@alfresco.com>.
On Mon, 27 Jun 2011, Brian Rosenberger wrote:
> Each element is exposed through a separate list, thus ordering is lost.

I think we should be maintaining a list with both paragraphs and tables in 
it though, with relative ordering preserved. On XWPFDocument there's
 	List<IBodyElement> bodyElements
for example, which is built by doing a child walk and storing the entries 
in the order they occur

I'd look at extending that to suit your needs

Nick

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org


AW: Replacing placeholder to a Table.

Posted by Brian Rosenberger <BR...@serena.com>.
Hi,

I have drilled down the problem to how xmlbeans exposes a <xsd:sequence> of <xsd:choice> where the available choices do not have a common basetype.

Here is an extract of CTBody schema from wml.xsd:
<xsd:choice>
      <xsd:element name="customXml" type="CT_CustomXmlBlock">
        <xsd:annotation>
          <xsd:documentation>Block-Level Custom XML Element</xsd:documentation>
        </xsd:annotation>
      </xsd:element>
      <xsd:element name="sdt" type="CT_SdtBlock">
        <xsd:annotation>
          <xsd:documentation>Block-Level Structured Document Tag</xsd:documentation>
        </xsd:annotation>
      </xsd:element>
      <xsd:element name="p" type="CT_P" minOccurs="0" maxOccurs="unbounded">
        <xsd:annotation>
          <xsd:documentation>Paragraph</xsd:documentation>
        </xsd:annotation>
      </xsd:element>
      <xsd:element name="tbl" type="CT_Tbl" minOccurs="0" maxOccurs="unbounded">
        <xsd:annotation>
          <xsd:documentation>Table</xsd:documentation>
        </xsd:annotation>
      </xsd:element>
      <xsd:group ref="EG_RunLevelElts" minOccurs="0" maxOccurs="unbounded" />
    </xsd:choice>

Each element is exposed through a separate list, thus ordering is lost. I have found how to preserve ordering when doing read access (http://article.gmane.org/gmane.text.xml.xmlbeans.user/2639/match=choice+sequence+order), but I don't have an idea how to write elements in a specific order as there is no shared list of them. My only current idea is to dump the xml of the bodyElements (CTP and CTTbl) into a string (with correct ordering) and the CTBody.Factory.parse them into a CTBody again. Very ugly.

Any better approaches?

Cheers
Brian

-----Ursprüngliche Nachricht-----
Von: Brian Rosenberger [mailto:BRosenberger@serena.com] 
Gesendet: Sonntag, 26. Juni 2011 17:58
An: user@poi.apache.org
Betreff: AW: Replacing placeholder to a Table.

Hi,

I am facing the same problem. The insertTable() method correctly adds the table into the body element list (correct position between two paragraphs). But when the document is written, all tables end up at the end of the document.
However tables inserted by ms word remain at their original location.

Cheers
Brian

-----Ursprüngliche Nachricht-----
Von: Mark Beardsley [mailto:markbrdsly@tiscali.co.uk]
Gesendet: Samstag, 26. Februar 2011 13:22
An: user@poi.apache.org
Betreff: Re: Replacing placeholder to a Table.

Hello again Andre,

I do not know if you are stil working on this problem but I have been a little today and can report no p[rogress at all. It is a trivial task to build a document sequentially; inserting a new paragraph followed by a table followed by another paragraph, etc, but I cannot yet find a way to insert a table between two existing paragraphs; whatever I try, the table simply appears at the end of the document.

I think that the key lies in one of two places - allowing us to directly update either the tables list or the body elements list, both of which are protected and so inaccessible to client code. To date, I have not looked at the source of the XWPF class but suspect that this is the way the
insertTable() and setTable() methods try to work. It would be perfect if we could use the set/insertTable methods to allow us to position a table in the document in it's correct location and I will look to see if this is possible. As always, will be in touch if I make any progress.

Yours

Mark B

--
View this message in context: http://apache-poi.1045710.n5.nabble.com/Replacing-placeholder-to-a-Table-tp3392424p3401338.html
Sent from the POI - User mailing list archive at Nabble.com.



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org For additional commands, e-mail: user-help@poi.apache.org




---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org