2009年7月1日 星期三

Openoffice與Lotus Notes整合 表格欄寬調整技巧

//***********************************************************
此斷程式碼使用來調整表格的欄寬,而OpenOffice調整欄寬的方式
與MS Word調整方式不一樣;OpenOffice的基準點是以表格欄與欄之間
分隔線所在的定位點往前或往後加減來調整欄寬。
假設:第一欄[oTblColSepsM( 0 ).Position =6000]位置所在為6000那要將欄調寬,
則是由原來的位置6000+1000 那欄寬就會加寬1000各單位
變成[oTblColSepsM( 0 ).Position =7000],第二欄由此類推。
//***********************************************************


Sub Click(Source As Button)
Dim objServiceManager As Variant
Dim objCoreReflection As Variant
Dim objDesktop As Variant
Dim objDocument As Variant
Dim objTable As Variant
Dim objCursor As Variant
Dim op As Variant

Dim objDispatch As Variant
Dim objRows As Variant
Dim objRow As Variant
Dim objCellCursor As Variant
Dim objCellText As Variant
Dim PageStyles As Variant
Dim StdPage As Variant
Dim sURL As String
Dim session As New NotesSession
Dim db As NotesDatabase
 

Dim args() As Variant
Dim argsEnd() As Variant
'The service manager is always the starting point
'If there is no office running then an office is started up

' Initialize the OpenOffice Environment
Set objServiceManager = CreateObject("com.sun.star.ServiceManager")
 

 Set objDesktop = objServiceManager.createInstance("com.sun.star.frame.Desktop")

' Initialize the Lotus Notes Environment
Set db = session.CurrentDatabase
' URL to create a new file

sUrl ="private:factory/swriter"
Set objDocument = objDesktop.loadComponentFromURL(sURL, "_blank", 0, args)

Set objDispatch = objServiceManager.createInstance("com.sun.star.frame.DispatchHelper")

Set PageStyles=objDocument.StyleFamilies.getByName("PageStyles")

Set objText= objDocument.getText()
Set objCursor= objText.createTextCursor()
' objCursor.gotoStart(False)
Set StdPage= PageStyles.getByName(objCursor.PageStyleName)
StdPage.IsLandscape=True
StdPage.Width=29700
StdPage.Height=21000
objCursor.CharFontName="Courier"
objCursor.CharHeight=10
objCursor.CharWeight=100
objCursor.CharHeight=10

Set objMTable= objDocument.createInstance( "com.sun.star.text.TextTable")


objMTable.initialize 1, 3
'Insert the table
objText.insertTextContent objCursor, objMTable, False
'Get first row
Set objRows= objMTable.getRows()
Set objRow= objRows.getByIndex(0)

Set objCellText= objMTable.getCellByName("A1")
Set objCellCursor= objCellText.createTextCursor()
' objCellCursor.setPropertyValue "CharColor",16777225
' objCellCursor.setPropertyValue "CharWeight", 75
objCellText.insertString objCellCursor, "第一欄",False


'-----------------------------------------
' Dim objCell As Variant
' Dim objCellCursorA As Variant
' Set objCell = objTable.getCellByName("A1")
' Set objCellCursorA = objTable.createCursorByCellName("A1")
objCellCursor.ParaAdjust = 2

'7.5 Setting Text Attributes
'http://api.openoffice.org/docs/common/ref/com/sun/star/awt/FontWeight.html#BOLD
' objCellCursor = objCellText.createTextCursorByRange()
' Dim objReformat
Set objReformat= objMTable.getCellRangeByName("A1:A1")
' Set objReformat= objTable.getCellByName("A1")
' objCellCursor.CharWeight =75
objReformat.CharWeightAsian=100
'-----------------------------------------------------

Dim oTblColSepsM As Variant
objMTable.LeftMargin = 100
objMTable.RightMargin = 100
Dim iWidth As Variant
iWidth=objMTable.Width
' Msgbox "iWidth: " & iWidth '115591 /11=9826.976
Dim objTableSum As Variant
objTableSum=objMTable.TableColumnRelativeSum
' Msgbox "objTableSum:="& objTableSum '10000
Dim dRatio As Double
dRatio=objTableSum/iWidth
' Msgbox "Ratio:"& dRatio '8.65111...
Dim dRelativeWidth As Double
dRelativeWidth=(1000*dRatio)/2 '約0.11公分
' Msgbox "dRelativeWidth:"&dRelativeWidth '173.02 約等於0.44公分
Dim dPosition As Double
dPosition=objTableSum-dRelativeWidth
' Msgbox "dPosition:&"& dPosition '9826.976
' Msgbox objTableSum '10000
'由此開始調整欄寬
oTblColSepsM = objMTable.TableColumnSeparators
oTblColSepsM( 0 ).Position =6000+1000
oTblColSepsM( 1 ).Position =7000+2000
objMTable.TableColumnSeparators = oTblColSepsM

'插入分頁
' objText.insertControlCharacter objCursor, 0 , False
' objCursor.BreakType=4 '//PAGE_BEFORE
objCursor.BreakType=5 '//PAGE_AFTER
objText.insertControlCharacter objCursor, 0 , False

End Sub

2009年6月18日 星期四

OpenOffice文件結構

這編文章主要在介紹OpenOffice Writer結構

API/Samples/Java/Writer/TextDocumentStructure

轉至:http://wiki.services.openoffice.org/wiki/API/Samples/Java/Writer/TextDocumentStructure
TextDocumentStructure
This example aims to demonstrate the basic structure of swriter text document and how iterating work.
The example has the following 4 aspects:
1.Initialize office and load bland document
2.Create example text
3.Iterating over text
4.Property State


Contents

[hide]

ONE: Initialize office and load bland document

Just like other examples:
connect to Office :declare Context -> through bootstrap to initialize the context -> get the Service manager of the context -> create Desktop instance ->querying XcomponentLoader interface -> load Component from URL (loadComponentFromURL method) -> then you'll have a document interface in Xcomponent type. All services and interface involved here has specific type:
Office Context : com.sun.star.uno.XComponentContext Service manager: com.sun.star.lang.XMultiComponentFactory Desktop: Object Component loader: com.sun.star.frame.XComponentLoader Document interface: com.sun.star.lang.XComponent



TWO: Create example text

At the first stage, we have got the document interface, thus the document is able to be manipulate via that interface.
Query the document for the XtextDocument interface (we are look at text document structure):
         // query the new document for the XTextDocument interface
          com.sun.star.text.XTextDocument xTextDocument =
              (com.sun.star.text.XTextDocument)UnoRuntime.queryInterface(
                  com.sun.star.text.XTextDocument.class, xComp);

Get document text interface(the interface to the all of document's text and its components):
            com.sun.star.text.XText xText = xTextDocument.getText();
com.sun.star.text.XText is derived from com.sun.star.sun.XSimpleText,inherited methods of XsimpleText and XtextRange, in addition with ability of inserting and removing XtextComponent. You also can see this kind of usage in the example of GraphicsInserter. XtextContent is specifyed in OpenOffice.org as:
enables objects to be inserted into a text and to provide their location in a text once they are inserted into it.

Methods called in this example are from XSimpleText specification, via insertString method to insert a string into document/Text, and then using Cursor (XwordCursor in this case) to iterate over Text and configurate it's format. In the examples of HardFormatting has detail demonstration about foramting. Formating text could be considered as configuring the propertySet of a TextRange (via a Cursor).

          xText.setString( "This is an example sentence" );

          com.sun.star.text.XWordCursor xWordCursor =
              (com.sun.star.text.XWordCursor)UnoRuntime.queryInterface(
                  com.sun.star.text.XWordCursor.class, xText.getStart());

          xWordCursor.gotoNextWord(false);
          xWordCursor.gotoNextWord(false);
          xWordCursor.gotoEndOfWord(true);

          com.sun.star.beans.XPropertySet xPropertySet =
              (com.sun.star.beans.XPropertySet)UnoRuntime.queryInterface(
                  com.sun.star.beans.XPropertySet.class, xWordCursor );
          xPropertySet.setPropertyValue("CharWeight",
                           new Float( com.sun.star.awt.FontWeight.BOLD ));
 
com.sun.star.awt module is Java AWT-like user interface toolkit interface specifications for UNO.



THREE:Iterating over text

Text has XenumerationAccess interface (inherited from XelementAccess for accessing collection), it enumerates all paragraphs in a text and returns objects which support com.sun.star.text.Paragraph. This includes tables, because writer sees tables as specialized paragraphs that support the com.sun.star.text.TextTable service. For information of TextTable, please visit: TextTable.
Paragraphs also have a com.sun.star.container.XEnumerationAccess of their own. They can enumerate every single text portion that they contain. A text portion is a text range containing a uniform piece of information that appears within the text flow. An ordinary paragraph, formatted in a uniform manner and containing nothing but a string, enumerates just a single text portion. In a paragraph that has specially formatted words or other contents, the text portion enumeration returns one com.sun.star.text.TextPortion service for each differently formatted string, and for every other text content. Text portions include the service com.sun.star.text.TextRange.
In a TextDocument,the relationship maybe:
 Text (1 has n ) paragraph ( 1 contains n) text portion (1 is n) character.

Breaking down the text document structure:


Step 1: create an enumeration access of all paragraphs of a document

            // create an enumeration access of all paragraphs of a document
          com.sun.star.container.XEnumerationAccess xEnumerationAccess =
              (com.sun.star.container.XEnumerationAccess)
                  UnoRuntime.queryInterface(
                      com.sun.star.container.XEnumerationAccess.class, xText);
          xParagraphEnumeration = xEnumerationAccess.createEnumeration();

Step 2: iterating over text's paragraphs,and create text portions for each paragraph

      while ( xParagraphEnumeration.hasMoreElements() ) {
        xTextElement = (com.sun.star.text.XTextContent)
             UnoRuntime.queryInterface(
                  com.sun.star.text.XTextContent.class,
                  xParagraphEnumeration.nextElement());
              ...
              ...
        // create another enumeration to get all text portions of 
        //the paragraph
        xParaEnumerationAccess =
             (com.sun.star.container.XEnumerationAccess)
                   UnoRuntime.queryInterface(
                       com.sun.star.container.XEnumerationAccess.class,
                           xTextElement);
        xTextPortionEnum = xParaEnumerationAccess.createEnumeration();
              ...
        //step 3  Through the Text portions Enumeration, get interface to each individual text portion
              ...
         }

Step 3: through the Text portions Enumeration, get interface to each individual text portion.

From the XnumerationAccess specification (including it's parent – XelementAccess), this container interface provides to access enumeration but not objects within the enumeration, thus, querying interface are required in order to obtain the interface to access those objects. As previous metioned, Text portions include the service com.sun.star.text.TextRange (for text manipulation).
while ( xTextPortionEnum.hasMoreElements() ) {
                      com.sun.star.text.XTextRange xTextPortion =
                          (com.sun.star.text.XTextRange)UnoRuntime.queryInterface(
                              com.sun.star.text.XTextRange.class,
                              xTextPortionEnum.nextElement());
                       ...
                       ...
}

FOUR:Property State

PropertyState, an enumeration lists the states that a property value can have (it's used as a member of struct com.sun.star.beans.PropertyValue).
The state consists of two aspects:
1.whether a value is available or void,
2.whether the value is stored in the property set itself or is a default, or ambiguous.
it has 3 Status/Values:
    com.sun.star.beans.PropertyState.DIRECT_VALUE:
  The value of the property is stored in the PropertySet itself.

  com.sun.star.beans.PropertyState.DEFAULT_VALUE:
  The value of the property is available from a master (e.g., template).

  com.sun.star.beans.PropertyState.AMBIGUOUS_VALUE:
  The value of the property is only a recommendation because
  there are multiple values for this property (e.g., from a multi selection).

In this example, property state of “CharWeight” in the Text portion was checked: (pay attention to PropertyState.****_VALUE and its related System.out.println() information)

    if( xPropertyState.getPropertyState("CharWeight").equals(
       com.sun.star.beans.PropertyState.AMBIGUOUS_VALUE) )
         System.out.println( "-  The text range contains more than one different attributes" );

  if( xPropertyState.getPropertyState( "CharWeight" ).equals(
       com.sun.star.beans.PropertyState.DIRECT_VALUE ) )
          System.out.println( " - The text range contains hard formats" );

  if( xPropertyState.getPropertyState( "CharWeight" ).equals(
       com.sun.star.beans.PropertyState.DEFAULT_VALUE ) )
          System.out.println( " - The text range doesn't contains hard formats" );
For details, please visit API document

2009年6月15日 星期一

透過LotesNotes建立Openoffice空白文件上建立表格並且插入列,並且「合併儲存格」

在OpenOfficeg上使用Basic語法「合併儲存」,不像在MS Word上來的便利
試了一天半終於測試出來的..感動..希望可以提供大家參考。各位也可以直接參考
以下這篇文章:
http://codesnippets.services.openoffice.org/WriterWriter.MergeTableCells.snip

'/==================================
'透過LotesNotes建立Openoffice空白文件
'上建立表格並且插入列,並且「合併儲存格」
'/==================================

Sub Click(Source As Button)
Dim objServiceManager As Variant
Dim objDesktop As Variant
Dim objDocument As Variant
Dim objTable As Variant
Dim objCursor As Variant

Dim objRows As Variant
Dim objRow As Variant
Dim objCellCursor As Variant
Dim objCellText As Variant

Dim sURL As String
Dim session As New NotesSession
Dim db As NotesDatabase
Dim args() As Variant
Dim argsEnd() As Variant

' Initialize the OpenOffice Environment
Set objServiceManager = CreateObject("com.sun.star.ServiceManager")
Set objDesktop = objServiceManager.createInstance("com.sun.star.frame.Desktop")

' Initialize the Lotus Notes Environment
Set db = session.CurrentDatabase
' URL to create a new file
sUrl ="private:factory/swriter"
Set objDocument = objDesktop.loadComponentFromURL(sURL, "_blank", 0, args)

Set objText= objDocument.getText()
Set objCursor= objText.createTextCursor()

Set objTable= objDocument.createInstance( "com.sun.star.text.TextTable")

objTable.initialize 2, 4
'Insert the table
objText.insertTextContent objCursor, objTable, False
'Get first row
Set objRows= objTable.getRows()
Set objRow= objRows.getByIndex(0)

Set objCellText= objTable.getCellByName("A1")
Set objCellCursor= objCellText.createTextCursor()
objCellCursor.setPropertyValue "CharColor",255
objCellText.insertString objCellCursor, "第一欄", False

'-----------------------------------------
' xTextTableCursor=xTextTable.createCursorByCellName("A"row) '-- create cursor
' xTextTableCursor=gotoCellByName("B"row, .true) '-- select area up toand including this cell
' xTextTableCursor=mergeRange '-- merge selectedcells

' insertIntoCell "A1","第一欄", objTable
' insertIntoCell "B1","第二欄", objTable
' insertIntoCell "C1","第三欄", objTable
' insertIntoCell "D1","加總", objTable
' insertByIndex( [in] long nIndex, [in] long nCount );
' com.sun.star.text.XTableRows xRows = xTextTable.getRows();
' insertByIndex( 6,4 ),objTable
' xRows.insertByIndex(xRows.getCount()-1, 0);
' 加入動態插入列
objRows.insertByIndex objRows.getCount(), 6
'測試合併儲存格
Dim objTextTableCursor As Variant
Set objTextTableCursor=objTable.createCursorByCellName("A1")
objTextTableCursor.gotoCellByName("A4") ,True
objTextTableCursor.mergeRange

End Sub