Copy/paste from Calc to Impress

Hi friends,

I’d like to copy a “table” (spreadsheet range) from a Calc spreadsheet to a new Impress document using a BASIC macro.

So far, I’ve been able to copy/paste using the clipboard through the Dispatcher.
What is blocking me, is that the pasted range doesn’t retain all of its formatting (for instance, numeric formats are kept, colors are not).
I’ve tried using cell styles, to no avail.

I attach a test spreadsheet with the copy/paste code for you to test.
paste_calc_table_to_impress.ods (34.6 KB). The entry point is Module1.Main.
I guess I overlooked something… Thanks for any pointers.

BTW, the pasted item is currently a (disconnected) OLE object, which I don’t need. I’d prefer a static GDI object. I couldn’t find information about how to do that. Any pointer as well?

In Impress, use Menu>Edit>Past special>Past special>Past special, where you can find different formats to paste. A couple of them graphics.

2 Likes

Thanks, @mariosv. I guess I wasn’t precise enough: I’d like to do that using a BASIC macro. I’ll have a few more ranges to copy/paste in the future, and doing that “by hand” – as is being done currently – will be tedious to say the least. I’ve updated the original question accordingly.

This approach can cause technical difficulties.
An easier (in my opinion) way is to create an alternative macro without using the clipboard: export the cell range in .png format and load it into Impress (Draw).
What’s your opinion?

1 Like

Hi Sokol92!

Yes, would be great. Unfortunately, I haven’t got any experience in this area (yet :slight_smile:
Any pointer appreciated.

Hi!

finally I got a track to the solution, after some browsing, thanks to @sokol92 for his image hint!

These links helped much in this area:

and
Apache OpenOffice Community Forum - [Solved] Insert an image into Draw document using Basic - (View topic)

Big thanks to @JohnSun and @Lupp who provided information on image manipulation. I’m on track now.

Have a good week-end,

Hello, @jfn!
I tried to create a more or less acceptable version of pasting preferred graphic format from the clipboard (see attachment).
If you’re satisfied with the result, I’d be happy to provide further clarification.
paste_calc_table_to_impress_2.ods (18.4 KB)

1 Like

Hi @sokol92 !

excellent! Much better result image quality than what I was with.

I’ll explore your code and learn from that.

Have a good week-end,

1 Like

Below is a short commentary and the macro text (this may be more convenient for some forum readers). Macro specifications precede their headers.

The InsertGraphicFromClipBoard macro scans all clipboard formats and selects data from the most appropriate mime type. The default value of the aMimeTypes parameter is subject to further discussion.

The InsertGraphicFromClipBoard macro creates a temporary file with data of the appropriate clipboard format and inserts this (graphic) file into a LibreOffice document (Calc, Writer, Impress, etc.).

The ShowClipboardContents macro is auxiliary and displays the clipboard contents (a list of all formats) in a new Calc document.

Option Explicit
Option Compatible

' Inserts an image into a LibreOffice document from a graphic file. 
' The mime type is detected automatically.  
Sub InsertGraphicFromFile(ByVal oDoc As Object, Byval filePath As String) As Boolean
  Dim props(0) as New com.sun.star.beans.PropertyValue
  Dim oDisp As Object
  oDisp = CreateUnoService("com.sun.star.frame.DispatchHelper")   
  props(0).Name = "FileName"
  props(0).Value = ConvertToUrl(filePath)
  oDisp.executeDispatch(oDoc.CurrentController.Frame, ".uno:InsertGraphic", "", 0, props)
End Sub


' Inserts an image into a LibreOffice document from Clipboard.
' The aMimeTypes parameter is described in `GetRelevantDataFromClipBoard` macro. 
Function InsertGraphicFromClipBoard(Optional ByVal oDoc As Object, Optional Byval aMimeTypes) As Boolean
  Dim clipData, oTempFile As Object, aData() As Byte
  If IsMissing(oDoc) Then oDoc = ThisComponent
  
  If IsMissing(aMimeTypes) Then 
    aMimeTypes = Array("application/x-openoffice-gdimetafile", "application/x-openoffice-emf", "image/svg+xml", "image/png", "image/*") ' ???
  End if  
 
  clipData= GetRelevantDataFromClipBoard(aMimeTypes) 
  If Not IsArray(clipData) Then Exit Function
  
  oTempFile = CreateUnoService("com.sun.star.io.TempFile")
  aData = clipData(2)
  oTempFile.writeBytes aData
  oTempFile.closeOutput
  InsertGraphicFromFile oDoc, oTempFile.Uri
  InsertGraphicFromClipBoard = True  
End Function


' Returns the preferred data format from the clipboard.
' aMimeTypes specifies an array of mime type names in descending order of preference.
' The mime type name is case-insensitive; the wildcard characters * and ? are allowed.
' If the preferred format is found, an array of three elements is returned: 
' the index; the DataFlavor structure; the clipboard data as a byte array.
' If the preferred format is not found, Empty is returned.
Function GetRelevantDataFromClipBoard(Byval aMimeTypes)
  Dim  oContents As Object, oTransferDataFlavors As Object
  Dim oDoc As Object, oSheet As Object
  Dim i As Long, arr, aData() As Byte, item
   
  GetRelevantDataFromClipBoard = Empty 
  oContents = CreateUnoService("com.sun.star.datatransfer.clipboard.SystemClipboard").getContents()
  If oContents Is Nothing Then Exit Function
  
  oTransferDataFlavors = oContents.getTransferDataFlavors()
  
  ReDim arr(Ubound(oTransferDataFlavors)) 
  For i=0 To Ubound(oTransferDataFlavors)
    arr(i) = oTransferDataFlavors(i).MimeType
    If Instr(1, arr(i), ";")>0 Then arr(i) = Split(arr(i), ";")(0)
  Next i     
  
  For Each item In aMimeTypes
    For i = 0 To Ubound(arr)
      If Lcase(arr(i)) Like Lcase(item) Then
        aData = oContents.getTransferData(oTransferDataFlavors(i)) 
        GetRelevantDataFromClipBoard = Array(i, oTransferDataFlavors(i), aData)
        Exit Function
      End If     
    Next i
  Next item      
 
End Function


' Shows the clipboard table of contents in a new Calc document.
Sub ShowClipboardContents()
  Dim  oContents As Object, oTransferDataFlavors As Object, oTransferDataFlavor As Object
  Dim oDoc As Object, oSheet As Object
  Dim i As Long, arr
   	
  oContents = CreateUnoService("com.sun.star.datatransfer.clipboard.SystemClipboard").getContents()
  If oContents Is Nothing Then Exit Sub
  oTransferDataFlavors = oContents.getTransferDataFlavors()
  
  ReDim arr(Ubound(oTransferDataFlavors)) 
  For i=0 To Ubound(oTransferDataFlavors)
    oTransferDataFlavor = oTransferDataFlavors(i)
    With oTransferDataFlavor
      arr(i) = Array(i, .HumanPresentableName, .MimeType)
    End With
  Next i
  
  oDoc = StarDesktop.LoadComponentFromUrl("private:factory/scalc","_default",0,Array())
  oSheet = oDoc.Sheets(0)
  oSheet.getCellRangeByPosition(0, 0, 2, 0).setDataArray Array(Array("Ind", "PresentableName", "Mime type"))
  oSheet.getCellRangeByPosition(0, 1, UBound(arr(0)), UBound(arr) + 1).setDataArray arr
  ' Format range.
  For i = 0 To 1
    oSheet.Columns(i).OptimalWidth=True
  Next i
End Sub
1 Like

Thank you @sokol92 for your help!

1 Like