1. Наш канал codeby в telegram. Пишем об информационной безопасности, методах защиты информации, о программировании. Не пропускай новости с кодебай, будь в тренде ! Подробнее ...

    Скрыть объявление

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

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

  1. Lia

    Lia New Member

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

    Репутация:
    3
    Регистрация:
    27 авг 2008
    Сообщения:
    6.406
    Симпатии:
    346
    это вот зачем? есть pipelining, есть postdomprocess (для DOM), есть serialize (тоже для DOM)
    --- Добавлено 27 апр 2015. Первое сообщение размещено 27 апр 2015 ---
    @rinsk в ртфм лОжил свой пример http://second-ext.inttrust.ru/Site/...0e1351cd15fa21a2c3256f5c00354fe7?OpenDocument
    "классику знать надо" :)
    --- Добавлено 27 апр 2015 ---
    надеюсь @rinsk простит, перепощу код (ссылку же дал)
    Код:
    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

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

    Lia New Member

    Репутация:
    0
    Регистрация:
    22 апр 2015
    Сообщения:
    4
    Симпатии:
    0
    Спасибо, буду разбираться.
    а по второму вопросу какие-либо соображения имеются?
    Ведь написав:
    в rawitemdata содержиться картинка в формате base64 ,
    а если я получаю base64 картинки данным скриптом
    Код:
    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, то
    Код:
    '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

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

    lmike нет, пердело совершенство
    Lotus team

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

    Вложения:

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

    lmike нет, пердело совершенство
    Lotus team

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

    lmike нет, пердело совершенство
    Lotus team

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

    lmike нет, пердело совершенство
    Lotus team

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

    lmike нет, пердело совершенство
    Lotus team

    Репутация:
    3
    Регистрация:
    27 авг 2008
    Сообщения:
    6.406
    Симпатии:
    346
    короткий резьюм по БД - агент исполняется над выделенными доками, результат складывает в ФС
    результат - все что есть приложенного или встроенного в док, имена задаются по значение миллисекунд + экстеншн
    для приложенных файлов - имя как в приложении
    используется SAX (с рефлексией - LAX, для кастомного расширения типа вложенных объектов) чтобы не жрать память
    --- Добавлено 29 апр 2015. Первое сообщение размещено 29 апр 2015 ---
    для большей экономии памяти - переделать на экспорт в файл (в коде - стринг)
     
    2 пользователям это понравилось.
  11. Lia

    Lia New Member

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

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

    Код:
    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 строку, а в определённую. Решила, что поставлю метку, и найду адрес строки с примечанием.
    Код:
     
    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

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

    Lia New Member

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

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

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

    lmike нет, пердело совершенство
    Lotus team

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

    lmike нет, пердело совершенство
    Lotus team

    Репутация:
    3
    Регистрация:
    27 авг 2008
    Сообщения:
    6.406
    Симпатии:
    346
    Код:
    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();
    			}
    		}
    	}
    }
    Код:
    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();
    				}
    			}
    		}
    	}
    }
    Код:
    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

    Репутация:
    3
    Регистрация:
    27 авг 2008
    Сообщения:
    6.406
    Симпатии:
    346
    закоменчен вариант с промежуточным файлом
    в 9.0.1 (да и в 8.х полагаю) путь ./ означает IBM\Notes\framework
    в системную консоль (Java Debug Console) выводится полный путь (сделал только для файла)
    Код:
    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();
    		}
    	}
    }
    
     
Загрузка...

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