![]() |
Delphi-Version: 2006
PDF in Datenbank speichern
Hallo zusammen,
ich speichere eine PDF in einer Datenbank folgendermassen:
Delphi-Quellcode:
Es gibt aber bei uns Rechner, da wird mit dieser Funktion zwar ein Stream in der Datenbank erzeugt, aber dieser lässt sich nicht mehr laden ?
procedure Datensatz_speichern_Pictures_PDF(Tabelle, Spalte, Filter_Spalte, Filter_Wert, Pfad:String; PDF_loeschen: Boolean);
var ms, outstream: TMemoryStream; begin ms := TMemoryStream.Create; outstream := TMemoryStream.Create; outstream.LoadFromFile(Pfad); outstream.Seek(0, soFromBeginning); DM_Main.QueryRaw.Close; DM_Main.QueryRaw.SQL[1] := Tabelle; DM_Main.QueryRaw.SQL[3] := Spalte; DM_Main.QueryRaw.SQL[5] := 'WHERE ' + Filter_Spalte; DM_Main.QueryRaw.ParamByName('p_pdf').SetBlobData(outstream.Memory, outstream.Size); DM_Main.QueryRaw.ParamByName('p_auftragsnummer').asstring := Filter_Wert; DM_Main.QueryRaw.ExecSQL; ms.Free; outstream.Free; if PDF_loeschen = true then begin DeleteFile(Pfad); end; end; Was kann das sein ? Muss ich eventuell beim speichern was anderes machen ? Oder müssen diese Streams dann anders geladen werden ? Gruss Holger |
AW: PDF in Datenbank speichern
Wenn ich das richtig sehe, wo sagst Du dem Stream, dass er etwas speichern soll ?
|
AW: PDF in Datenbank speichern
Also ich speichere meine Dokumente in einem Firebird-Blob so:
Delphi-Quellcode:
Übergeben wird einfach der Dateiname und das Blobfeld. Zuvor wird natürlich der Datensatz zum Editieren vorbereitet, und auch das Post erfolgt nicht in der Funktion. Die erledigt nur das reine Einlesen einer Datei in ein Blobfeld.
Function TDatMod.DateiToBlob(Datei: String; Blobfeld: TField): Boolean;
VAR S : TStream; FileS : TFileStream; begin Result := FALSE; S := BlobFeld.DataSet.CreateBlobStream(BlobFeld, bmReadWrite); TRY FileS := TFileStream.Create(Datei, fmOpenRead); S.CopyFrom(FileS, FileS.Size); Result := TRUE; FINALLY FileS.Free; S.Free; END; end; Um eine im Blob gespeicherte PDF- oder HTML-Datei im Embedded WebBrowser anzuzeigen, gehe ich z.B. so vor:
Delphi-Quellcode:
procedure TFormDoku.DokumentLaden;
Var PersistStreamInit : IPersistStreamInit; StreamAdapter : IStream; MemoryStream : TMemoryStream; Stream : TStream; Blobfeld : TField; begin Blobfeld := DatMod.Qset_NewsLink.FieldByName('INHALT'); Stream := BlobFeld.DataSet.CreateBlobStream(BlobFeld, bmRead); EmbWeb.Navigate('about:blank'); // Leeres HTML-Dokument in Browser laden um ein valites HTML-Dokument zu erzeugen // wait until finished loading Repeat Application.ProcessMessages; Sleep(0); Until EmbWeb.ReadyState = READYSTATE_COMPLETE; // Get IPersistStreamInit - Interface IF EmbWeb.Document.QueryInterface(IPersistStreamInit, PersistStreamInit) = S_OK THEN BEGIN IF PersistStreamInit.InitNew = S_OK THEN // Clear document BEGIN // Make local copy of the contents of Stream if you want to use Stream directly, you have to // consider, that StreamAdapter will destroy it automatically MemoryStream:= TMemoryStream.Create; Try MemoryStream.CopyFrom(Stream, 0); MemoryStream.Position:= 0; Except FreeAndNil(MemoryStream); Raise; End; StreamAdapter:= TStreamAdapter.Create(MemoryStream, soOwned); // Use Stream-Adapter to get IStream Interface to our stream PersistStreamInit.Load(StreamAdapter); // Load data from Stream into WebBrowser END; END; IF Assigned(Stream) THEN FreeAndNil(Stream); IF Assigned(Blobfeld) THEN FreeAndNil(Blobfeld); end; |
AW: PDF in Datenbank speichern
Zitat:
|
AW: PDF in Datenbank speichern
Zitat:
Wie würdest du das machen? |
AW: PDF in Datenbank speichern
|
AW: PDF in Datenbank speichern
Zitat:
|
AW: PDF in Datenbank speichern
Zitat:
Stell dir vor du hast 10.000 Dokumente. Alle basieren auf das gleiche Layout. Verwenden also gleiche CSS/HTML/JS-Elemente. Mit dem MIME-Ansatz werden die mehrfach verwendeten Elemente 10.000* kopiert und in 10.000 Blob-Felder gespeichert. Im Rahmen eines Redesigns der HTML-Seiten wird z.B. eine CSS-Angepasst. Man muss also 10.000 Blob-Felder aktualisieren (bzw. prüfen). Zitat:
|
AW: PDF in Datenbank speichern
Folgende SQL-Funktion steckt hinter der DM_Main.QueryRaw:
Delphi-Quellcode:
Kann es sein das ich vielleicht hier was verändern muss ? -> outstream.Seek(0, soFromBeginning);
UPDATE
SYSDBP.DBP_AUFTRAGEX SET = :p_pdf WHERE AUFTRAGSNUMMER = :p_auftragsnummer Gruss Holger |
AW: PDF in Datenbank speichern
Habe mir jetzt folgende Funktion gebastelt:
Delphi-Quellcode:
Wie speichere ich aber jetzt die PDF in der Datenbank ?
function Datensatz_speichern_Pictures_PDF2(Tabelle, Spalte, Filter_Spalte, Filter_Wert, Pfad:String; PDF_loeschen: Boolean):Boolean;
var blob : TStream; FileS : TFileStream; begin Result := FALSE; DM_Main.TableRaw.Close; DM_Main.TableRaw.TableName := Tabelle; DM_Main.TableRaw.Filter := Filter_Spalte + '=' + Filter_Wert; DM_Main.TableRaw.Filtered := TRUE; DM_Main.TableRaw.Open; blob := DM_Main.TableRaw.CreateBlobStream(DM_Main.TableRaw.FieldByName(Spalte), bmRead); blob.Seek(0, soFromBeginning); try FileS := TFileStream.Create(Pfad, fmCreate); FileS.CopyFrom(blob, blob.Size); finally FileS.Free; blob.Free; end; if PDF_loeschen = true then begin DeleteFile(Pfad); end; Result := TRUE; end; |
AW: PDF in Datenbank speichern
Ich versteh den Sinn der ganzen Funktion nicht so richtig, wieso holst Du ein PDF aus einem BLOB-Feld, speicherst dies in eine Datei und löschst diese im Anschluss ggf. gleich wieder? Vom kreativen Gebrauch von Ressourcenschutzblöcken und Boolean-Vergleichen mal ganz abgesehen. Und wenn man einen BLOBStream mit bmRead zum Lesen erzeugt, wie muss es dann wohl zum Schreiben aussehen?
|
AW: PDF in Datenbank speichern
Ich verstehe selber zur Zeit gar nichts mehr.
Es geht mir darum, dass mir vielleicht eine andere Möglichkeit aufgezeigt wird eine PDF-Datei in eine Tabelle mit einer LONGRAW-Spalte zu schreiben, als wie ich Sie benutze, da komischerweise an bestimmten PC's (Ich nenne Sie mal CN-PCs) bei uns im Hause zwar mit meiner Eingangs geposteten Funktion ein Stream gespeichert wird, dieser aber nicht mehr ausgelesen werden kann ? Soll heissen: Folgende Auslesefunktion funktioniert bei allen PC's:
Delphi-Quellcode:
Folgende Funktion speichert den Stream in der Datenbank. Nur wenn der Stream über die CN-PCs gespeichert wird kann man diesen Stream mit der obigen Funktion nicht mehr laden.
function Datensatz_auslesen_Picture_PDF(Tabelle, Spalte, Filter_Spalte, Filter_Wert, Pfad:String):Boolean;
var fs: TFileStream; blob: TStream; begin Result := FALSE; DM_Main.TableRaw.Close; DM_Main.TableRaw.TableName := Tabelle; DM_Main.TableRaw.IndexFieldNames := Filter_Spalte; DM_Main.TableRaw.Filter := Filter_Spalte + ' = ' + Filter_Wert + ''; DM_Main.TableRaw.Filtered := TRUE; DM_Main.TableRaw.Open; if DM_Main.TableRaw[Spalte] = '' then exit; blob := DM_Main.TableRaw.CreateBlobStream(DM_Main.TableRaw.FieldByName(Spalte), bmRead); blob.Seek(0, soFromBeginning); fs:=TFileStream.Create(Pfad, fmCreate); fs.CopyFrom(blob, blob.Size); fs.Free; blob.Free; Result := TRUE; end;
Delphi-Quellcode:
Es geht mir darum eine andere Möglichkeit des speicherns von PDF-Dateien in eine Datenbank aufgezeigt zu bekommen, oder eventuell mal Hinweise was ich an der "Speicher-Funktion" mal testweise verändern sollte um dem Fehler auf den Grund zu gehen ?
procedure Datensatz_speichern_Pictures_PDF(Tabelle, Spalte, Filter_Spalte, Filter_Wert, Pfad:String; PDF_loeschen: Boolean);
var ms, outstream: TMemoryStream; begin ms := TMemoryStream.Create; outstream := TMemoryStream.Create; outstream.LoadFromFile(Pfad); outstream.Seek(0, soFromBeginning); DM_Main.QueryRaw.Close; DM_Main.QueryRaw.SQL[1] := Tabelle; DM_Main.QueryRaw.SQL[3] := Spalte; DM_Main.QueryRaw.SQL[5] := 'WHERE ' + Filter_Spalte; DM_Main.QueryRaw.ParamByName('p_pdf').SetBlobData(outstream.Memory, outstream.Size); DM_Main.QueryRaw.ParamByName('p_auftragsnummer').asstring := Filter_Wert; DM_Main.QueryRaw.ExecSQL; ms.Free; outstream.Free; if PDF_loeschen = true then begin DeleteFile(Pfad); end; end; Gruss Holger |
AW: PDF in Datenbank speichern
Ich fand die Herangehensweise von Perlsau gar nicht schlecht, Feld und Dateinamen als einzige Parameter an eine Methode zu übergeben.
|
AW: PDF in Datenbank speichern
Nur fehlte da das speichern ? Wie mache ich das denn dann ?
|
AW: PDF in Datenbank speichern
Zitat:
Ich finde Deine Methode der SQL-Text-Erzeugung ein wenig obskur. Zitat:
Gruß K-H |
AW: PDF in Datenbank speichern
Wieso fehlt das Speichern? Wir reden doch beide von #3, oder?
|
AW: PDF in Datenbank speichern
Nee nicht das Speichern, sondern die gespeicherten Daten!
(Soll alles schon vorgekommen sein.) Gruß K-H |
AW: PDF in Datenbank speichern
Zitat:
|
AW: PDF in Datenbank speichern
Perlsau schrieb in #3 aber
Zitat:
Gruss Holger |
AW: PDF in Datenbank speichern
Zitat:
Delphi-Quellcode:
Das funktioniert so sicher & zuverlässig, daß ich die Quelldatei (ob nun PDF oder HTML) danach einfach löschen kann.
DatMod.Qset_NewsLink.Edit;
DatMod.Qset_NewsLink.FieldByName('EXISTIERT').AsBoolean := Existiert; IF FileExists(Dateiname) THEN BEGIN DatMod.DateiToBlob(Dateiname,DatMod.Qset_NewsLink,DatMod.Qset_NewsLink.FieldByName('INHALT')); DeleteFile(Dateiname); END; DatMod.Qset_NewsLink.Post; |
AW: PDF in Datenbank speichern
Alles klar.
Habe es jetzt mal für mich etwas umgebaut:
Delphi-Quellcode:
Nur leider werden keine Daten gespeichert. Wo ist der Fehler ?
function Datensatz_speichern_PDF(Tabelle, Spalte, Filter_Spalte, Filter_Wert, Pfad:String; PDF_loeschen: Boolean):Boolean;
var S : TStream; FileS : TFileStream; BlobFeld: TField; begin Result := FALSE; DM_Main.TableRaw.Close; DM_Main.TableRaw.TableName := Tabelle; DM_Main.TableRaw.IndexFieldNames := Filter_Spalte; DM_Main.TableRaw.Filter := Filter_Spalte + ' = ' + Filter_Wert + ''; DM_Main.TableRaw.Filtered := TRUE; DM_Main.TableRaw.Open; DM_Main.TableRaw.Edit; BlobFeld := DM_Main.TableRaw.FieldByName(Spalte); S := BlobFeld.DataSet.CreateBlobStream(BlobFeld, bmReadWrite); try FileS := TFileStream.Create(Pfad, fmOpenRead); S.CopyFrom(FileS, FileS.Size); DM_Main.TableRaw.Post; Result := TRUE; finally FileS.Free; S.Free; end; end; Gruss Holger |
AW: PDF in Datenbank speichern
"Zurückspulen" vergessen?
|
AW: PDF in Datenbank speichern
Wenn ich vor dem "try" folgenden Code eingebe:
Delphi-Quellcode:
bringt das ncihts, wenn Du das meinst ?
S.Seek(0, soFromBeginning);
Gruss Holger |
AW: PDF in Datenbank speichern
Zitat:
Wenn ich das richtig sehe, speicherst du alles immer in den ersten Record (Open setzt den Datensatzzeiger auf den ersten Record). Möchtest du einen neuen Datensatz anlegen, dann muß es natürlich Append oder Insert statt Edit heißen. Wenn du einen bestehenden Datensatz bearbeiten möchtest, solltest du zuvor den gewünschten Datensatz lokalisieren. |
AW: PDF in Datenbank speichern
Zitat:
|
AW: PDF in Datenbank speichern
Ich filtere ja die TTable vorher auf einen bestimmten Datensatz und wenn ich dann "open" machen müsste doch dieser Datensatz geöffnet werden, oder ?
Wenn ich jetzt aber .edit gegen .append austausche klappt es auch nciht. Überprüfen tue ich das mit dem SQl-Developer, ob in der Spalte nun Daten vorhanden sind. Was könnte an meinem Code ncoh falsch sein ? Gruss Holger |
AW: PDF in Datenbank speichern
Zitat:
Wieso beläßt du die Function zum Einlesen der PDF-Datei in ein Blobfeld nicht so, wie ich sie dir gezeigt habe, und erledigst alles andere in der aufrufenden Methode? Dann könntest du nämlich deine Daten_To_Blob-Funktion für alle denkbaren Fälle verwenden, auch zum Einlesen von Bildern oder sonstwas, auch zum Einlesen in andere Blob-Felder usw. Zudem würde dein Code dadurch übersichtlicher. Lokalisiere also in der aufrufenden Methode den gewünschten Datensatz, setze deine Table-Komponente auf Append, Insert oder Edit, rufe die Einlese-Function auf und übergebe ihr die beiden Parameter Dateiname und Blobfeld, und danach machst du in der aufrufenden Methode Post und gibst die erzeugte Table-Komponente wieder frei. Das wäre sauberer Programmierstil. Unsauber ist es, wenn man versucht, alles in eine Funktion oder Prozedur zu quetschen. |
AW: PDF in Datenbank speichern
Zitat:
|
AW: PDF in Datenbank speichern
Zitat:
|
AW: PDF in Datenbank speichern
Guten morgen zusammen,
mir ist nun aufgefallen, dass bei mir in der Zeile
Delphi-Quellcode:
das FileS.Size = 0 ist ?
S.CopyFrom(FileS, FileS.Size);
Ist das richtig ? Gruss Holger |
AW: PDF in Datenbank speichern
Sofern die Datei leer ist...
|
AW: PDF in Datenbank speichern
Commando zurück.
War leider alles ein Irrtum meinerseits. Wenn man mit einer PDF testet welche 0 KB hat. Warum auch immer ? Die war mal OK. Und wenn man hinter dem onclick-Ereignis des Buttons vergisst die Funktion aufzurufen, welche die PDF wieder lädt, dann kann das auch nichts werden. Gestern war wohl nicht mein Tag. Danke trotzdem an alle und ich habe nun eine alternative Speicher-Funktion für JPG, PDF etc. ... Gruss Holger |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:12 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz