Импорт картики richtextitem в excel, используя dxl

Тема в разделе "Lotus - Программирование", создана пользователем Lia, 27 апр 2015.

  1. Lia

    Lia New Member

    Регистрация:
    22 апр 2015
    Сообщения:
    4
    Симпатии:
    0
    Задача следующая:
    1)достать из RTI картинку в формате base64;
    2)потом её сохранить в формате jpg;
    3)вставить в нужную ячейку Excel.
    Вот что у меня пока что выходит:
    Код (LotusScript):

    Dim s As NotesSession
    Dim db As NotesDatabase
    Dim inputstream As NotesStream
    Dim exporter As NotesDXLExporter
    Dim domparser As NotesDOMParser
    Dim rootElement As NotesDOMElementNode
    Dim docNode As NotesDOMDocumentNode
    Dim docList As NotesDOMNodeList
    Dim itemList As NotesDOMNodeList    'list of <item> nodes
    Dim node As NotesDOMNode            'an <item> node
    Dim aNode As NotesDOMAttributeNode  'a "name" attribute
    Dim i As Integer
    Dim pictureBase64 As String
     
    Dim filename As String
    fileName = "c:\InputFile.dxl"
     
    Set db = curdoc.Parentdatabase
    Set s = db.Parent
    Set inputstream = s.Createstream
     
    If inputstream.Open(fileName) Then
    Call inputstream.Truncate()
    Set exporter = s.Createdxlexporter
    exporter.OutputDOCTYPE = False
    exporter.RichTextOption = RICHTEXTOPTION_RAW
    Call exporter.SetInput(doc)
    inputstream.Writetext(exporter.Export(doc))
    Set domparser = s.CreateDOMParser
    Call domparser.setinput(exporter)
    Call exporter.Process 'стало проскакивать
    Set docNode = domparser.Document
    Set rootElement = domParser.Document.DocumentElement
    Set doclist = rootElement.Getelementsbytagname("*")
    If docList.NumberOfEntries = 0 Then
    MessageBox "No <document> element nodes in file", , "Error"
    Exit Sub
    End If
    Set itemlist = docnode.Getelementsbytagname("item")
    If itemList.NumberOfEntries = 0 Then
    MessageBox "No <item> element nodes in file", , "Error"
    Exit Sub
    End If
    For i = 1 To itemList.NumberOfEntries
    Set node = itemList.GetItem(i)
    Set aNode = node.Attributes.Getitem(1)
    If anode.AttributeValue = "Signature" Then
    pictureBase64 = node.Lastchild.Lastchild.Nodevalue
    MessageBox  pictureBase64  
    End If
    Next
    End If
     
    'Dim objXML As Variant
    'Dim objDocElem As Variant
    'Dim writebytes As Variant
    'Dim objStream As Variant
     
    'Set objXML = CreateObject("MSXml2.DOMDocument")
    'Set objDocElem = objXML.createElement("tmp")
    'objDocElem.DataType = "bin.base64"
    'objDocElem.text = pictureBase64
    'writeBytes = objDocElem.NodeTypedValue
    'Set objStream = CreateObject("ADODB.Stream")
    'objStream.Type = 1 ' TypeBinary
    'objStream.Open
    'objStream.Write writeBytes 'write binary data to a binary Stream object.
    'objStream.SaveToFile "C:\Temp\test.jpg", 2
     
     
    Суть проблемы, что почему-то стало выкидывать на этапе Call exporter.Process . Почему?
    А до этого я получала pictureBase64 картинки и пыталась преобразовать. Но его нельзя было открыть/прочитать. Потом я взяла отдельно преобразовала картинку в форма base64 и там совершенно другой набор символов :( Что я упускаю?
     
  2. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.083
    Симпатии:
    300
    это вот зачем? есть pipelining, есть postdomprocess (для DOM), есть serialize (тоже для DOM)
    [DOUBLEPOST=1430143135,1430142877][/DOUBLEPOST]@rinsk в ртфм лОжил свой пример http://second-ext.inttrust.ru/Site/...0e1351cd15fa21a2c3256f5c00354fe7?OpenDocument
    "классику знать надо" :)
    [DOUBLEPOST=1430143405][/DOUBLEPOST]надеюсь @rinsk простит, перепощу код (ссылку же дал)
    Код (LotusScript):
    Class AttPictureSetClass
        ''''''''''''
        s As NotesSession
        db As NotesDatabase
        doc As NotesDocument
        ''''''''''''
        attExt As String
        attExtList List As Variant
        '''''''''''
        Public dxp As NotesDXLExporter
        Public par As NotesDOMParser
        Public dip As NotesDXLImporter
        '''''''''''
        Sub New
            Set s=New NotesSession
            Set db=s.CurrentDatabase
        End Sub
        Function ProcessObject (obj As Variant, dbexport As NotesDatabase)
            Set Me.dxp = Me.s.CreateDXLExporter(obj)
            Me.dxp.ConvertNotesbitmapsToGIF=True
            Set Me.par = Me.s.CreateDOMParser(Me.dxp)
            On Event PostDOMParse From par Call ProcessDOM
            Set Me.dip = Me.s.CreateDXLImporter(Me.par, dbexport)
            Me.dip.DocumentImportOption=DXLIMPORTOPTION_UPDATE_ELSE_IGNORE
            Me.dip.DesignImportOption=1
            Me.dip.ReplaceDBProperties=False
            Me.dip.ReplicaRequiredForReplaceOrUpdate=False
            Call Me.dxp.Process
            ProcessObject=Me.dxp.Log
        End Function
        Private Sub ProcessDom (Source As NotesDOMParser)
            Dim rtNode As NotesDOMNodeList
            Dim AtRefList As NotesDOMElementNode
            Dim attExt As String
            Dim attList List As Variant
            Set rtNode=Source.Document.GetElementsByTagName("attachmentref")
            For x=1 To rtNode.NumberOfEntries
                Set AtRefList=rtNode.GetItem(x)
                attExt=LCase(StrRightBack(atRefList.GetAttribute("displayname"),"."))
                If IsElement(Me.attExtList(attExt)) Then
                    Call atRefList.SetAttribute("caption",atRefList.GetAttribute("displayname"))
                    AtRefList.FirstChild.FirstChild.FirstChild.NodeValue=Me.attExtList(attExt)
                End If
            Next
            Source.Serialize
        End Sub
        Public Sub GetImageRes
            Dim nc As NotesNoteCollection
            Dim GifNodeList As NotesDOMNodeList
            Dim GifNode As NotesDOMNode
            Dim ParentObj As NotesDOMElementNode
            Set nc=s.CurrentDatabase.CreateNoteCollection(False)
            nc.SelectImageResources=True
            nc.SelectionFormula=|@Matches($TITLE;"_att_.???")|
            Call nc.BuildCollection
            If nc.count>0 Then
                Set par = s.CreateDOMParser()
                Set dxp = s.CreateDXLExporter(nc,par)
                dxp.ConvertNotesbitmapsToGIF=True
                Call dxp.Process
                Set GifNodeList=par.Document.GetElementsByTagName("gif")
                For k=1 To GifNodeList.NumberOfEntries
                    Set GifNode=GifNodeList.GetItem(k)
                    Set ParentObj=GifNode.ParentNode
                    Me.AttExtList(LCase(StrRightBack(ParentObj.GetAttribute("alias"),".")))=GifNode.FirstChild.NodeValue
                Next
            End If
        End Sub
        Sub Delete
            If Not Me.db Is Nothing Then Delete Me.db
            If Not Me.s Is Nothing Then Delete Me.s
        End Sub
    End Class
    Sub Initialize
        Dim s As New NotesSession
        Dim db As NotesDatabase
        Dim doc As NotesDocument
        Dim cl As NotesDocumentCollection
        '''''''''''''''
        Dim attObj As AttPictureSetClass
        '''''''''''''''
        Set db=s.CurrentDatabase
        Set doc=db.UnprocessedDocuments.GetFirstDocument
        Set attObj=New AttPictureSetClass
        Call attObj.GetImageRes
        attObj.ProcessObject doc,db
    End Sub
     
    #2 lmike, 27 апр 2015
    Последнее редактирование модератором: 27 апр 2015
  3. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.083
    Симпатии:
    300
  4. Lia

    Lia New Member

    Регистрация:
    22 апр 2015
    Сообщения:
    4
    Симпатии:
    0
    Спасибо, буду разбираться.
    а по второму вопросу какие-либо соображения имеются?
    Ведь написав:
    в rawitemdata содержиться картинка в формате base64 ,
    а если я получаю base64 картинки данным скриптом
    Код (LotusScript):
    Set objStream = CreateObject("ADODB.Stream")
    objStream.Type = 1 ' TypeBinary
    objStream.Open()
    objStream.LoadFromFile("C:\Temp\test.jpg")
    readBytes = objStream.Read()
    Set objXML = CreateObject("MSXml2.DOMDocument")
    objXML.loadXML "<Base64Data />"
    Set objDocElem = objXML.documentElement
    objDocElem.dataType = "bin.base64"
    objDocElem.nodeTypedValue = readBytes
    textBase64 = objDocElem.text
    ,то получаю другой набор символов.

    Тое сть набор символов не совпадает

    И если я преобразовываю в jpg base64 из rawitemdata, то
    Код (Text):
    'Dim objXML As Variant
    'Dim objDocElem As Variant
    'Dim writebytes As Variant
    'Dim objStream As Variant
     
    'Set objXML = CreateObject("MSXml2.DOMDocument")
    'Set objDocElem = objXML.createElement("tmp")
    'objDocElem.DataType = "bin.base64"
    'objDocElem.text = pictureBase64
    'writeBytes = objDocElem.NodeTypedValue
    'Set objStream = CreateObject("ADODB.Stream")
    'objStream.Type = 1 ' TypeBinary
    'objStream.Open
    'objStream.Write writeBytes 'write binary data to a binary Stream object.
    'objStream.SaveToFile "C:\Temp\test.jpg", 2
    получаю ошибку
    this not vlid bitmap file, or it format not currently supported.

    а если используя textBase64 , то та же картика отображается.
     
  5. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.083
    Симпатии:
    300
    не используете КОМ чуть менее чем везде ;)
    в домине достаточно бриджей для работы с base64 без COM
    второе - я не совсем понимаю, вернее - не понимаю, зачем использовать RAW?
    картинки итак хранятся в base64 в DXL, как пример картинка в РТ безо всяких RAW, будет в тегах - <picture width='2048px' height='1536px'><jpeg>Здесь base64</jpeg></picture>
    [DOUBLEPOST=1430223423,1430223163][/DOUBLEPOST]как дернуть картинку - ну например с пом. XSLT
    [DOUBLEPOST=1430223653][/DOUBLEPOST]еще (фигтекогда выкладывал) http://web3.inttrust.ru/site/itforu...0bbcd2d7a458ff78c3257482005cad87!OpenDocument
    если без внешних либ - LAX
     
  6. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.083
    Симпатии:
    300
    вот тестовая база - положить (скопировать и буфера) любой док, запустить SAX test агент - получить файло в String rootPath="c:\\" + fsep + "files" + fsep;
     

    Вложения:

    • SAXtest.zip
      Размер файла:
      2 МБ
      Просмотров:
      11
    #6 lmike, 28 апр 2015
    Последнее редактирование модератором: 28 апр 2015
  7. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.083
    Симпатии:
    300
    может вывалить эксепшн - надо экспортеру запретить использовать DTD
    создать диру c:\files - оно туда хочет сохранять
     
  8. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.083
    Симпатии:
    300
    вернее так - в тек класспаз должен лежать domino.dtd
    в ранних версиях домины (до 7-ой) оно само находило диру xmlschemas (где все и лежит)
    но в 9-ке оно мажет ;)
     
  9. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.083
    Симпатии:
    300
    патч - там приложен код exporter.setDoctypeSYSTEM(binPath.toString()+File.separatorChar + "xmlschemas"+File.separatorChar+"domino_6_5_4.dtd");
    кот. надо раскоментить, для задачи непринципиально, а 6.5.4 присут. в это месте
     
  10. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.083
    Симпатии:
    300
    короткий резьюм по БД - агент исполняется над выделенными доками, результат складывает в ФС
    результат - все что есть приложенного или встроенного в док, имена задаются по значение миллисекунд + экстеншн
    для приложенных файлов - имя как в приложении
    используется SAX (с рефлексией - LAX, для кастомного расширения типа вложенных объектов) чтобы не жрать память
    [DOUBLEPOST=1430299784,1430299714][/DOUBLEPOST]для большей экономии памяти - переделать на экспорт в файл (в коде - стринг)
     
    2 пользователям это понравилось.
  11. Lia

    Lia New Member

    Регистрация:
    22 апр 2015
    Сообщения:
    4
    Симпатии:
    0
    вроде всё заработало!)

    3)вставить в нужную ячейку Excel.

    Код (LotusScript):
    xlFilename = "c:\СБД\XLS\" + curdoc.DocName(0) + ".xls"
    Set Excel = createObject("Excel.Application")
    Excel.Visible = true
    Excel.Workbooks.Open(xlFilename)
    Set xlWorkbook = Excel.ActiveWorkbook
    Set xlSheet = xlWorkbook.ActiveSheet
    Set xlCells = xlSheet.Cells
    row = 27
    Excel.Rows(row).Select
    Excel.Selection.ClearContents
    xlCells(row,1).Value = curdoc.FromPost(0)
    xlCells(row,5).Value = curdoc.FromName(0)
    'вставка картинки
    Dim r As Variant
    Set r = xlSheet.Range("C25")'положение левого верхнего угла картинки
    xlSheet.Shapes.AddPicture "C:\Temp\test.jpg", False, True, r.Left, r.Top, 80, 80
    Excel.Quit
    но теперь понадобилось вставлять не в 27 строку, а в определённую. Решила, что поставлю метку, и найду адрес строки с примечанием.
    Код (LotusScript):

     
    Set r = xlSheet.Cells.Find("sign")
    If r Is Nothing Then
    MessageBox "no"
    End If
     
    r заполняется [Object], но не могу достучаться до адреса ячейки с меткой. Про проверки на Nothing return True
    Поэтому когда пытаюсь получить address or row , ошибка Object variable not set.
     
  12. oshmianski

    oshmianski Достойный программист
    Lotus team

    Регистрация:
    25 апр 2012
    Сообщения:
    521
    Симпатии:
    13
    Этак вы до Excel XML Spreadsheet + XSLT скоро дотянете.
    Бросьте Вы этот COM, не тратьте на него время.
     
  13. Lia

    Lia New Member

    Регистрация:
    22 апр 2015
    Сообщения:
    4
    Симпатии:
    0
    а на что тратить?

    каким путём дальше идти?

    п.с. Сильно не ругайте, я только месяц как месяц познакомилась с лотусом)
     
  14. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.083
    Симпатии:
    300
    ответ выше
    еще есть POI
    это меньше всего влияет на решаемую задачу, при условии понимания - что есть ХМЛ и знания, например java
     
  15. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.083
    Симпатии:
    300
    Код (Java):
    import lotus.domino.*;
    import java.io.*;
     
    public class JavaAgent extends AgentBase {
        Thread thread1;
        Thread thread2;
     
        public void NotesMain() {
     
            try {
                Session session = getSession();
                AgentContext agentContext = session.getAgentContext();
     
                // (Your code goes here)
                Document doc = agentContext.getDocumentContext();
     
                StringBuffer binPath = new StringBuffer(session
                        .getEnvironmentString("NotesProgram", true));
                if (binPath.length() == 0) {
                    String sttmp = session.getEnvironmentString("Directory", true);
                    binPath.append(session.getEnvironmentString("Directory", true));
                    if (binPath.charAt(binPath.length() - 1) == File.separatorChar)
                        binPath.setLength(binPath.length() - 1);
                    binPath.setLength(binPath.toString().lastIndexOf(
                            File.separatorChar));
                }
                System.out.println("Program Path:" + binPath.toString());
                PipedInputStream in = new PipedInputStream();
                final PipedOutputStream out = new PipedOutputStream(in);
                thread1 = new NotesThread(new DataSource(doc, out));// new
                                                                    // FileOutputStream("./out.dxl")));
                thread1.start();
                // thread1.join();
                thread2 = new NotesThread(new DataConsumer(in));// new
                                                                // FileInputStream("./out.dxl")));
                thread2.start();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    thread1.join();
                    thread2.join();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
    Код (Java):
    import java.io.BufferedWriter;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
     
    import lotus.domino.*;
     
    public class DataSource implements Runnable {
        private Document doc = null;
        private OutputStream outs = null;
     
        public DataSource(Document xdoc, OutputStream stream) {
            outs = stream;
            doc = xdoc;
        }
     
        @Override
        public void run() {
            try {
                BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outs,
                        "utf-8"));
                System.out.println("*" +this.getClass().getName()+" ->doc's generating...");
                doc.generateXML(bw);
                bw.flush();
                outs.flush();
                outs.close();
                System.out.println("*" +this.getClass().getName()+" ->doc's generated");
                outs = null;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                System.out.println("quit DataSource");
                if (outs != null) {
                    try {
                        outs.flush();
                        outs.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    Код (Java):
    import java.io.File;
    import java.io.InputStream;
     
    import lotus.notes.NotesThread;
     
    public class DataConsumer implements Runnable {
        private InputStream inputStream = null;
     
        public DataConsumer(InputStream inputStream) {
            this.inputStream = inputStream;
        }
     
        public void run() {
            Lax lax = new Lax();
            // Создаем инстансы классов, кот. обрабатывают конкретные элементы XML
            FileData fdata = new FileData("."
                    + (new Character(File.separatorChar)).toString());
            GifData gifData = new GifData("."
                    + (new Character(File.separatorChar)).toString());
            JpegData jpegData = new JpegData("."
                    + (new Character(File.separatorChar)).toString());
            // Подключаем их к автоматическому хендлеру
            // в классе д.б. методы textOf<элемент> (для обработки содержимого) и
            // start<элемент>, end<элемент> - для условий начала и окончания
            // элемента
            lax.addHandler(jpegData);
            lax.addHandler(gifData);
            lax.addHandler(fdata);
            System.out.println("procesing...");
            lax.parseDocument(true, lax, inputStream);
        }
    }
     
    #15 lmike, 30 апр 2015
    Последнее редактирование модератором: 30 апр 2015
  16. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.083
    Симпатии:
    300
    закоменчен вариант с промежуточным файлом
    в 9.0.1 (да и в 8.х полагаю) путь ./ означает IBM\Notes\framework
    в системную консоль (Java Debug Console) выводится полный путь (сделал только для файла)
    Код (Java):
    import org.xml.sax.*;
    import java.io.*;
    import org.base64.util.*;
     
    public class FileData {
        // private String fileName="";
        private FileOutputStream outFile = null;
        private StringBuffer sBuff = new StringBuffer("");
        private String rootPath = "";
        private String filePath = "";
        private File fobj = null;
     
        public FileData(String path) {
            super();
            rootPath = path;
        }
     
        public void textOffiledata(String fileData) {
            // System.out.print(fileData);
            sBuff.append(fileData);
        }
     
        public void startfile(AttributeList list) {
            // за название берем системное время в мс
            filePath = rootPath + list.getValue("name");
            fobj = new File(filePath);
        }
     
        public void startfiledata(AttributeList list) {
            System.out.print("start file->");
            openStream(fobj);
        }
     
        public void endfiledata() {
            closeStream();
            System.out.println("<-end file");
        }
     
        // *************************************************
        private void openStream(File f) {
            try {
                outFile = new FileOutputStream(f);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
     
        private void closeStream() {
            try {
                if (outFile != null) {
                    outFile.write(Base64.decode(sBuff.toString()));
                    outFile.close();
                    System.out.println(fobj.getAbsolutePath());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
     
     
Загрузка...
Похожие Темы - Импорт картики richtextitem
  1. ToxaRat
    Ответов:
    11
    Просмотров:
    624
  2. magistr
    Ответов:
    25
    Просмотров:
    1.762
  3. ty3uk
    Ответов:
    16
    Просмотров:
    1.947
  4. Ali002
    Ответов:
    0
    Просмотров:
    1.119
  5. toli4sky
    Ответов:
    27
    Просмотров:
    3.202

Поделиться этой страницей