Dawid Wanaciuk

Dawid Wanaciuk Software Developer

Temat: Potrzebna pomoc open office 4 w c#

Cześć

Czy ktoś tutaj zna się na wykorzystaniu Open Office z poziomu C#? Szukałem w necie ale informacji na ten temat jest bardzo mało i jest porozrzucana po forach i blogach a większość przykładów jest dla Javy, VB i C++. W dodatku nie ogarniam jeszcze UNO i nie bardzo wiem gdzie i czego szukaća nie mam czasu na przeglądanie całego helpa. Chodzi o merge fields w szablonach rtf. Mam też problem z uruchomieniem OO 4 w .NET i leci wyjątek zaraz przy uruchamianiu, zanim jeszcze wejdzie do jakiegokolwiek konstruktora. W Wordzie to było banalne bo wystarczyło dodać jedną referencję a Worda startowało się w dwóch linijkach a tutaj to jest zagmatwane.

Proszę o pomoc a nie odsyłanie mnie do google.

Temat: Potrzebna pomoc open office 4 w c#

Wykorzystuję Apache OO 4 do tworzenia raportów w oparciu o mergefields. Mogę spróbować pomóc. Czego konkretnie potrzebujesz?

Co do wyjątku to czy dodałeś do AppConfiga w sekcji configuration:
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" />
</startup>


DLLki OO są kompilowane pod target 2.0 i bez tego nie ruszy.
Dawid Wanaciuk

Dawid Wanaciuk Software Developer

Temat: Potrzebna pomoc open office 4 w c#

OK, zadziałało. Dzięki za pomoc!

A teraz kolejny problem. Mam w szablonie pola, które występują zarówno samodzielnie jak i tworzą kolekcje danych w relacji master-details. Chcę zbudować drzewo zawierające te pola, aby potem wygodnie je podmieniać z użyciem rekurencji. O ile w Wordzie pola w kolekcji Fields występują w kolejności takiej, jak w dokumencie, to w OO getTextFields zwracane je bez ładu i składu. Bez ich uporządkowania nie dam rady zbudować drzewa. Myślałem, żeby im ponadawać jakieś identyfikatory i posortować, ale mam kilkaset szablonów, a poza tym jest zakaz ich przerabiania. Ktoś je kiedyś zaprojektował tak, że jedynie ich kolejność mówi o ich relacji. Wiesz może, jak uzyskać kolejność taką, jak w Wordzie? I gdybyś mógł podawać namespacey albo usingi, bo jest ich tyle, że głowa boli.

Temat: Potrzebna pomoc open office 4 w c#

Rozumiem, co chcesz uzyskać :) Sam tworzyłem podobne rozwiązanie pod pewien znany system do obsługi szpitali. Faktycznie OO to trochę komplikuje, jednak spokojnie możesz uzyskać listę pól w takim porządku, jak występują w dokumencie. Co ciekawe, iterator zawsze startuje od pierwszego pola (sprawdzałem wielokrotnie), dopiero potem czasem się "gubi". Musisz utworzyć widok dokumentu, po którym będziesz "skakał" od pola do pola i zapisywał je oraz jego położenie (X, Y) do tymczasowej kolekcji. Później musisz posortować tę kolekcję najpierw po Y (1 wiersz, 2 wiersz etc.) a potem po X (od lewej do prawej). I masz kolekcję pól tak, jak wystepują w dokumencie. Oczywiście pod warunkiem, że nie masz tam jakichś ramek z pozycjonowaniem absolutnym, tabel z "merdżowanymi" wierszami/kolumnami i faktycznie geometryczny układ pól odzwierciedla ich logiczną kolejność.

PS: zakładam, że masz już zainicjowany xComponent

usingi (mogą być nadmiarowe, pousuwaj zbędne):
using unoidl.com.sun.star.lang;
using unoidl.com.sun.star.uno;
using unoidl.com.sun.star.bridge;
using unoidl.com.sun.star.frame;
using unoidl.com.sun.star.text;
using unoidl.com.sun.star.container;
using unoidl.com.sun.star.util;
using unoidl.com.sun.star.view;
using unoidl.com.sun.star.beans;
using uno.util;
using uno;


public List<XTextField> GetOrderedDocumentFields()
{
XTextDocument document = (XTextDocument) this.xComponent;
XTextViewCursorSupplier xViewCursorSupplier = (XTextViewCursorSupplier) document.getCurrentController();
XTextViewCursor xTextViewCursor = xViewCursorSupplier.getViewCursor();

XEnumerationAccess documentFields = ((XTextFieldsSupplier) this.xComponent).getTextFields();
XEnumeration docFields = documentFields.createEnumeration();

List<FieldWithCoords> fieldsWithCoordinates = new List<FieldWithCoords>();

while (docFields.hasMoreElements())
{
XTextField nextField = docFields.nextElement().Value as XTextField;
xTextViewCursor.gotoRange(nextField.getAnchor(), false);

fieldsWithCoordinates.Add(new FieldWithCoords(nextField,
xTextViewCursor.getPosition().X,
xTextViewCursor.getPosition().Y));
}

return fieldsWithCoordinates.OrderBy(m => m.Y).ThenBy(m => m.X).ToList().Select(m=>m.Field).ToList();
}

private class FieldWithCoords
{
public XTextField Field { get; private set;}
public int X { get; private set; }
public int Y { get; private set; }

public FieldWithCoords(XTextField field, int x, int y)
{
this.Field = field;
this.X = x;
this.Y = y;
}
}


PS: jeśli zamierzasz coś potem robić z tym dokumentem, np. drukować, musisz "zrestartować" widok, tj. ustawić kursor na początku dokumentu:

xTextViewCursor.gotoStart(false);
Ten post został edytowany przez Autora dnia 04.11.13 o godzinie 20:04
Dawid Wanaciuk

Dawid Wanaciuk Software Developer

Temat: Potrzebna pomoc open office 4 w c#

Cześć,

Dzięki za odpowiedź, działa jak trzeba. Zasłużony plus. Ale mam jeszcze jeden problem. W Wordzie było tak, że po zaznaczeniu Range miałem dostęp do zawartych w nim pól przez Range.Fields, a tutaj nie mogę znaleźć nic podobnego. Za dużo jest tych interfejsów. Zaznaczam blok tekstu kursorem XTextViewCursor, tworzę z niego iterator, ale żaden z elementów nie implementuje interfejsu XTextField ani podobnych. Czy można się jakoś dobrać do listy pól w danym zaznaczeniu od - do? Wiem, że w kotwicy pola są jego współrzędne, więc teoretycznie można by sprawdzać, czy są w zadanym prostokącie?

Temat: Potrzebna pomoc open office 4 w c#

W przypadku RTFów też nie mogłem kursorem znaleźć nic poza paragrafami i tabelami. Co do pomysłu z badaniem współrzędnych pól to trafiłeś w dziesiątkę, tylko z jednym ważnym "ale": zaznaczenie może nie być prostokątem.

Obrazek


List<XTextField> GetFieldsCollectionInRange(int xLower, int yLower, int xUpper, int yUpper)
{
List<XTextField> fields = new List<XTextField>();

XTextViewCursorSupplier cursorSupplier = (XTextViewCursorSupplier)this.document.getCurrentController();
XTextViewCursor viewCursor = cursorSupplier.getViewCursor();

XEnumerationAccess documentFields = ((XTextFieldsSupplier)this.document).getTextFields();
XEnumeration docFields = documentFields.createEnumeration();

XTextRange oldPosition = viewCursor.getStart();
int xNew, yNew;
while (docFields.hasMoreElements())
{
XTextField field = docFields.nextElement().Value as XTextField;
viewCursor.gotoRange(field.getAnchor(), false);

xNew = viewCursor.getPosition().X;
yNew = viewCursor.getPosition().Y;

bool isInOneLineBetweenPoints = xNew >= xLower && yNew == yLower && xNew < xUpper && yLower==yUpper;
bool isInFirstLineAfterPoint = xNew >= xLower && yNew == yLower && xNew < xUpper;
bool isBetweenLines = yNew > yLower && yNew < yUpper;
bool isInLastLineBeforePoint = xNew < xUpper && yNew == yUpper;

if (isInOneLineBetweenPoints || isInFirstLineAfterPoint || isBetweenLines || isInLastLineBeforePoint)
{
fields.Add(field);
}
}
viewCursor.gotoRange(oldPosition, false);
return fields;
}


Tablicę możesz potem posortować po X i Y, jeśli będziesz w niej trzymał koordynaty pól - jak wyżej.

Następna dyskusja:

Potrzebna pomoc w analizie ...




Wyślij zaproszenie do