Hello dear experts,
I would need to mass extract from DWG drawings some OLE objects (Excel sheets which are BOM).
Is it possible to use temporary license to test, before mid-term implementation ?
I’m more efficient with python programming at this stage, is the python library full functional or is .NET more capable ?
Thanks (if someone already did the job - scripting, I would be happy to share…)
Rgds
Ronan
Can you please provide more details about the specific OLE objects you want to extract from the DWG drawings and clarify your question regarding the functionality of the Python library compared to .NET?
Sure, we have list of equipment in Excel table, embedded into DWG drawing as show on picture below. as we need to mass treat the data, we would like to extract Excel files "out of "the DWG for computation.
Plates_Screenshot 2024-11-27 174743.png (20,1 Ko)
My question regarding the python library is the foloowing : does the current python library provide the same functionalities than .NET library (regarding OLE interaction), or are there some limitations in python library which would force me to migrate to .NET dev ?
Thanks and regards,
Ronan
@Ronan_COLMOU,
Hello.
We have reading of OLE objects but not interpreting them. Ole2Frame.BinaryData contains the content of the file.
import aspose.cad as cad
from aspose.pycore import cast
file_name = ""
image = cad.Image.load(file_name)
with cast(cad.fileformats.cad.CadImage, image) as cad_image:
for entity in cad_image.entities:
if entity.type_name == cad.fileformats.cad.cadconsts.CadEntityTypeName.OLE2FRAME:
ole2_frame = cast(cad.fileformats.cad.cadobjects.CadOle2Frame,entity)
print(ole2_frame.binary_data)
The functional is the same, here is the example for .NET.
using (CadImage cadImage = (CadImage)Aspose.CAD.Image.Load(fileName))
{
foreach (CadEntityBase ceb in cadImage.Entities)
{
if (ceb.TypeName == CadEntityTypeName.OLE2FRAME)
{
CadOle2Frame ole2Frame = (CadOle2Frame)ceb;
// ole2Frame.BinaryData
}
}
}
Perfect thanks, and to export this binary data to xls file, should I go through aspose.cells or can it be done directly ?
If I add the following, the output file is not accepted by Excel :
file_path = “export.xls”
with open(file_path, “wb”) as file:
binary_data = ole2_frame.binary_data
file.write(binary_data)
@Ronan_COLMOU,
That’s not so easy unfortunately, because binary data are not the content of some file directly, but represent Compound File Binary format (CFB) that stores file inside. You need to parse this stream and get the file from it. Please note that binary data may have some excess bytes at the beginning before CFB starts. Probably, compoundfiles or cfb python packages (or some other similar) could be helpful.
Thanks a lot for that,
We finally succeed in treatment of mass extract of Excel BOM from DWG drawing, with the attached script, using :
- aspose.CAD library for extraction of OLE2frame
- aspose.cells library for “repair”/conversion of xls file (simple open/close was enough, as your library make the repair by itself)
Please note : - ACAD files positively treated are AC1027 and later (from version 2013). Not sure it works for AC1024, but does not work for previous versions ( AC1021). See Codes de version des formats de dessin pour AutoCAD
- Not sure the removal of first 22bytes (to start with OLE magic) in OLE2Frame is still needed, but it works as below, so we kept it…
Congratulations for your work on libraries, it’s really powerful and helpful.
On our side, we will see how the need will evolve and will confirm related licenses accordingly.
Thanks.
import os
import aspose.cad as cad
from aspose.pycore import cast
import aspose.cells
from aspose.cells import Workbook
from aspose.cells import License
def traiter_fichier_dwg(file_name):
#Traite un fichier DWG spécifique pour extraire des données OLE et les enregistrer.
#Args: file_name (str): Chemin du fichier DWG à traiter.
try:
print(f"Loading file : {file_name}")
# Charger le fichier DWG
image = cad.Image.load(file_name)
with cast(cad.fileformats.cad.CadImage, image) as cad_image:
nb_entities = 0
ole_data_found = False
# Parcourir les entités du fichier
for entity in cad_image.entities:
nb_entities += 1
print(f"Analyzed entities : {nb_entities}")
if entity.type_name == cad.fileformats.cad.cadconsts.CadEntityTypeName.OLE2FRAME:
ole2_frame = cast(cad.fileformats.cad.cadobjects.CadOle2Frame, entity)
file_path = f"{os.path.splitext(file_name)[0]}_{nb_entities}_export.xls"
# Enregistrer les données OLE dans un fichier Excel
with open(file_path, "wb") as file:
binary_data = ole2_frame.binary_data
file.write(binary_data[22:-1])
# repair Excel
workbook = Workbook(f"{os.path.splitext(file_name)[0]}_{nb_entities}_export.xls")
workbook.save(f"{os.path.splitext(file_name)[0]}_{nb_entities}_export_repaired.xls")
ole_data_found = True
print(f"OLE2FRAME found and exported in : {file_path}")
#print(f"Total number of entities : {nb_entities}")
if not ole_data_found:
print(f"No OLE data found in {file_name}")
except Exception as e:
raise Exception(f"Error during treatment of file {file_name}: {e}")
def traiter_repertoire_dwg(repertoire):
# Traite tous les fichiers DWG dans un répertoire donné et gère les erreurs.
# Args: repertoire (str): Chemin du répertoire contenant les fichiers DWG.
fichiers_en_erreur = []
# Vérifier si le répertoire existe
if not os.path.isdir(repertoire):
print(f"Directory {repertoire} doesn't exist.")
return
# Parcourir les fichiers DWG dans le répertoire
for fichier in os.listdir(repertoire):
if fichier.lower().endswith(".dwg"):
chemin_fichier = os.path.join(repertoire, fichier)
try:
traiter_fichier_dwg(chemin_fichier)
except Exception as e:
print(e)
fichiers_en_erreur.append(chemin_fichier)
# Enregistrer les erreurs dans un fichier texte
if fichiers_en_erreur:
chemin_erreurs = os.path.join(repertoire, "erreurs.txt")
with open(chemin_erreurs, "w") as fichier_erreur:
fichier_erreur.write("\n".join(fichiers_en_erreur))
print(f"List of files generating error {chemin_erreurs}")
else:
print("All files successfully managed.")
if __name__ == "__main__":
# Définir la licence pour Aspose.CAD
lic = cad.License()
lic.set_license(r'Aspose.CADforPythonvia.NET.lic')
# Définir la licence pour Aspose.cells
lic_cells = License()
lic_cells.set_license(r'Aspose.CellsforPythonvia.NET.lic')
repertoire = input("Enter folder name where DWG files are located : ").strip()
traiter_repertoire_dwg(repertoire)
@Ronan_COLMOU,
Happy to hear and thank you for kind words.
If you can share the details what exactly doesn’t work for AC1021, for instance, provide test file we can investigate this case.