RAF078 2024-09-21 07:59 采纳率: 60%
浏览 24
已结题

求合并两个字节流VB6代码

#求合并两个字节流保存到一个PDF文件VB6代码
#将一个PDF字节流保存到PDF文件是正常的
#源代码如下:

'导出合并字节流PDF,导出合并PDF
Public Sub Export_MergePDFfile(ContractNum As String, imagePath As String)
Dim imageData() As Byte
Dim imageData1() As Byte
Dim imageData2() As Byte

Dim Stream1 As New ADODB.stream
Dim Stream2 As New ADODB.stream
Dim outputStream As New ADODB.stream

If rs.State <> adStateClosed Then rs.Close
rs.Open "select 发票图片,合同图片 from 合同PDF where 合同编号='" & ContractNum & "'", cnn, adOpenStatic, adLockReadOnly
If rs.RecordCount < 1 Then
    MsgBox "该合同还没有添加图片!", vbExclamation
    rs.Close
    Exit Sub
End If
  
imageData1 = rs.Fields(0).Value    ' “图片”字段是OLE对象类型
' 配置流
Stream1.Type = adTypeBinary
Stream1.Open
Stream1.Write imageData1 ' 将第一个PDF文件的字节流写入输出流
    
imageData2 = rs.Fields(1).Value
' 配置流
Stream2.Type = adTypeBinary
Stream2.Open
Stream2.Write imageData2 ' 将第二个PDF文件的字节流写入输出流

'' 合并流
outputStream.Type = adTypeBinary ' 设置为二进制模式  1
outputStream.Open
'    outputStream.Write Stream1.Read      '报错!
'    outputStream.Write Stream2.Read

outputStream.Write imageData1
outputStream.Write imageData2
'可以正常写入一个流到PDF文件,但不能合并,写入两个流时后面的会将第一个覆盖。显示的PDF只有imageData2的。

'' 将第二个流的内容追加到第一个流
'Stream1.CopyTo outputStream, -1   '保存的文件打不开,提示已损坏。
'Stream2.CopyTo outputStream, -1

' 保存合并后的PDF到文件
outputStream.SaveToFile imagePath, adSaveCreateOverWrite  'adSaveCreateNotExist=1 ' 2 '1-不允许覆盖,2-覆盖写入
' 关闭流和记录集对象
outputStream.Close

Stream1.Close
Stream2.Close
rs.Close
Set outputStream = Nothing
Set Stream1 = Nothing
Set Stream2 = Nothing
Set rs = Nothing
Exit Sub

#这是一个以前的VB6源代码,将一个字节流保存到PDF是正常的,
#现在需要将两个字节流合并并保存到一个PDF文件。
#特向各位老师求教
#目前各位老师的解答还没有解决问题
#采用合并字节流方式都存在没有合并PDF字节流,第二个字节流覆盖了第一个。
#采用第三方PDFtk工具方式时,第一次可以合并2个PDF文件并输出合并后的文件成功。但再次调用就没有输出文件了。不报错。

#继续期待老师们的指点!谢谢!

  • 写回答

21条回答 默认 最新

  • 杨同学* 2024-09-21 22:08
    关注

    该回答引用ChatGPT4o及杨同学*共同作答, 如有帮助,还请采纳。
    在VB6中处理两个PDF字节流的合并问题,简单的字节流拼接是行不通的,因为PDF文件是结构化的文档格式,直接拼接不同的PDF文件的字节流会破坏PDF的结构,导致无法正确打开。要正确合并PDF文件,需要使用特定的PDF合并工具或库。

    解决方案:使用第三方工具合并PDF

    尽管VB6本身不提供合并PDF的内建功能,你可以尝试通过以下方式解决问题:

    1. 使用PDFtk工具合并PDF
      PDFtk 是一个非常实用的命令行工具,可以用于PDF文件的合并、拆分、加密等操作。你可以先将每个字节流保存为单独的PDF文件,然后使用PDFtk合并它们。

    2. VB6中调用PDFtk进行合并
      你可以在VB6中通过 Shell 命令执行PDFtk的命令行操作。

    使用PDFtk合并PDF的步骤:

    1. 保存字节流到文件
      先将每个字节流保存为单独的PDF文件(例如 file1.pdffile2.pdf)。

    2. 使用PDFtk合并PDF文件
      然后,使用PDFtk将 file1.pdffile2.pdf 合并为一个新的PDF文件(例如 merged.pdf)。

    修改后的VB6代码

    Public Sub Export_MergePDFfile(ContractNum As String, imagePath As String)
        Dim imageData1() As Byte
        Dim imageData2() As Byte
        Dim Stream1 As New ADODB.stream
        Dim Stream2 As New ADODB.stream
    
        ' 保存每个字节流到单独的PDF文件
        Dim tempPath1 As String
        Dim tempPath2 As String
        tempPath1 = App.Path & "\temp1.pdf"
        tempPath2 = App.Path & "\temp2.pdf"
    
        ' 获取数据库中的PDF数据
        If rs.State <> adStateClosed Then rs.Close
        rs.Open "select 发票图片,合同图片 from 合同PDF where 合同编号='" & ContractNum & "'", cnn, adOpenStatic, adLockReadOnly
        If rs.RecordCount < 1 Then
            MsgBox "该合同还没有添加图片!", vbExclamation
            rs.Close
            Exit Sub
        End If
    
        imageData1 = rs.Fields(0).Value ' 获取第一个PDF字节流
        imageData2 = rs.Fields(1).Value ' 获取第二个PDF字节流
    
        ' 保存第一个PDF字节流到临时文件
        Stream1.Type = adTypeBinary
        Stream1.Open
        Stream1.Write imageData1
        Stream1.SaveToFile tempPath1, adSaveCreateOverWrite
        Stream1.Close
    
        ' 保存第二个PDF字节流到临时文件
        Stream2.Type = adTypeBinary
        Stream2.Open
        Stream2.Write imageData2
        Stream2.SaveToFile tempPath2, adSaveCreateOverWrite
        Stream2.Close
    
        ' 调用PDFtk合并PDF
        Dim pdftkCommand As String
        pdftkCommand = "pdftk """ & tempPath1 & """ """ & tempPath2 & """ cat output """ & imagePath & """"
    
        ' 使用Shell运行PDFtk命令来合并PDF
        Shell pdftkCommand, vbNormalFocus
    
        ' 清理临时文件
        Kill tempPath1
        Kill tempPath2
    
        rs.Close
        Set Stream1 = Nothing
        Set Stream2 = Nothing
        Set rs = Nothing
    End Sub
    

    解释:

    1. 保存字节流到文件

      • 使用 ADODB.stream 对象将每个PDF的字节流保存为一个临时文件(如 temp1.pdftemp2.pdf)。
    2. 调用PDFtk命令

      • 使用 Shell 函数调用PDFtk来合并这两个临时文件。
      • pdftkCommand 变量构造了PDFtk的命令行,该命令将 temp1.pdftemp2.pdf 合并到 imagePath 指定的目标PDF文件中。
    3. 清理临时文件

      • 合并完成后,删除临时的PDF文件。

    PDFtk工具获取和安装

    你可以从 PDFtk官网 下载PDFtk Server并将其安装到系统中,确保 pdftk 命令可以在命令行中使用。

    总结:

    使用VB6直接处理PDF字节流进行合并是不行的,因为PDF格式结构复杂,直接拼接会导致文件损坏。最佳方案是将字节流保存为单独的PDF文件,再借助第三方工具(如PDFtk)进行合并操作。

    希望这些步骤能帮助你解决问题。如果你还有其他疑问,欢迎继续交流!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(20条)

报告相同问题?

问题事件

  • 系统已结题 10月3日
  • 已采纳回答 9月25日
  • 修改了问题 9月21日
  • 创建了问题 9月21日