本人初学vc,客户要求我用sql2000数据库存储word文档,要求可以读取,修改,保存(直接操作数据库),我郁闷了2天了,没能解决,那位高手有相关的材料给小第一份,不胜感激(由于初学vc,最好有源程序),我现在有1040分愿意全部奉上!!
email: [email protected]

解决方案 »

  1.   

    读写image字段的例子:
    void CImageDlg::OnAdd() 
    {
    // TODO: Add your control notification handler code here
    char szPath[MAX_PATH];
    char pBuffer[BUFFERSIZE];
    int r; if(!m_bInitialized)
    {
    AfxMessageBox("Db-Library not intialized.");
    return;
    }
    //get filename
    szPath[0] = '\0';
    CFileDialog FileDialog(TRUE, NULL, szPath,
    OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST,
    "图象文件|*.JPG;*.JPEG;*.BMP||",
    this);
    FileDialog.m_ofn.lpstrTitle = "增加文件";
    if(FileDialog.DoModal() == IDCANCEL)
    return;
    strcpy(szPath, FileDialog.GetPathName());
    FILE* fp;
    fp = fopen(szPath, "rb");
    if(fp == NULL)
    {
    AfxMessageBox("Open file failed!");
    return;
    }
    //get file length
    long filelen;
    fseek(fp, 0, SEEK_END);
    filelen = ftell(fp);
    fseek(fp, 0, SEEK_SET); //clear dbprocess
    dbcancel(m_pDbProc);
    //insert a new row
    dbcmd(m_pDbProc, "DECLARE @ID BINARY(16)");
    dbcmd(m_pDbProc, "SELECT @ID = NewID()");
    dbfcmd(m_pDbProc, "INSERT INTO testimage VALUES(@ID, '%s', 0x01)",
    szPath + FileDialog.m_ofn.nFileOffset); 
    dbcmd(m_pDbProc, "SELECT * FROM testimage WHERE ImageID = @ID");
    if(dbsqlexec(m_pDbProc) == FAIL)
    {
    AfxMessageBox("Fail to Insert a new record!");
    dbcancel(m_pDbProc);
    fclose(fp);
    return;
    }
    dbresults(m_pDbProc); //SELECT @ID = NewID(): discard results
    dbresults(m_pDbProc); //INSERT INTO ... discard results
    //get results
    if((r = dbresults(m_pDbProc)) == FAIL)
    {
    AfxMessageBox("Fail to get result!");
    dbcancel(m_pDbProc);
    fclose(fp);
    return;
    }
    else if(r == NO_MORE_RESULTS)
    {
    AfxMessageBox("No more results!");
    dbcancel(m_pDbProc);
    fclose(fp);
    return;
    }
    //bind columns
    char acID[37];
    dbbind(m_pDbProc, 1, NTBSTRINGBIND, (DBINT)0, (unsigned char*)acID);
    dbbind(m_pDbProc, 2, NTBSTRINGBIND, (DBINT)0, (unsigned char*)szPath);
    dbbind(m_pDbProc, 3, NTBSTRINGBIND, (DBINT)1, (unsigned char*)pBuffer);
    if(dbnextrow(m_pDbProc) == NO_MORE_ROWS)
    {
    AfxMessageBox("New row not found!");
    dbcancel(m_pDbProc);
    fclose(fp);
    return;
    }
    //save TextPtr & TextTimeStamp
        DBBINARY aTextPointer[DBTXPLEN];
    DBBINARY aTextTimestamp[DBTXTSLEN];
        DBBINARY *pTextPointer;
    DBBINARY *pTextTimestamp;
    pTextPointer = dbtxptr(m_pDbProc, 3);
    pTextTimestamp = dbtxtimestamp(m_pDbProc, 3);
    memcpy(aTextPointer, pTextPointer, DBTXPLEN);
    memcpy(aTextTimestamp, pTextTimestamp, DBTXTSLEN); //get 'NO_MORE_ROWS'
    dbnextrow(m_pDbProc);
        //get NO_MORE_RESULTS to clear out all results
    dbresults (m_pDbProc); //call dbwritetext will NULL text value to indicate that the text
    //values will be sent in chunks using dbmoretext
    if(dbwritetext(m_pDbProc, "testimage.ImageBody", aTextPointer,
    DBTXPLEN, aTextTimestamp, FALSE, filelen, NULL) == FAIL)
    {
    AfxMessageBox("dbwritetext failed!");
    dbcancel(m_pDbProc);
    fclose(fp);
    return;
    }

    // call dbsqlok and dbresults to prepare for calling dbmoretext
    if(dbsqlok(m_pDbProc) == FAIL)
    {
    AfxMessageBox("Image write failed.");
    dbcancel(m_pDbProc);
    fclose(fp);
    return;
    }
    if(dbresults(m_pDbProc) == FAIL)
    {
    AfxMessageBox("Query result failed.");
    dbcancel(m_pDbProc);
    fclose(fp);
    return;
    }// long tl = 0;
    while((r = fread(pBuffer, sizeof(char), BUFFERSIZE, fp)) > 0)
    {
    // tl += r;
    if(dbmoretext(m_pDbProc, r, (unsigned char*)pBuffer) == FAIL)
    {
    AfxMessageBox("error in more text!");
    dbcancel(m_pDbProc);
    fclose(fp);
    return;
    }
    }
    // wsprintf(pBuffer, "%ld bytes stored into database", tl);
    // AfxMessageBox(pBuffer); fclose(fp); //call dbsqlok and dbresults to signal end of calls to
    //dbmoretext and completion of text or image write
    if(dbsqlok(m_pDbProc) == FAIL)
    {
    AfxMessageBox("Text or image write failed.");
    dbcancel(m_pDbProc);
    return;
    }
    if(dbresults(m_pDbProc) == FAIL)
    {
    AfxMessageBox("Query results failed.");
    dbcancel(m_pDbProc);
    return;
    }
    //Insert this row into listbox
    int nIndex = m_ImageList.AddString(szPath);
    char* p = new char[37];
    ConvertGUID(acID, p);
    m_ImageList.SetItemDataPtr(nIndex, p);
    }void CImageDlg::OnExtract() 
    {
    // TODO: Add your control notification handler code here
    char szPath[MAX_PATH];
    char pBuffer[BUFFERSIZE];
    if(!m_bInitialized)
    {
    AfxMessageBox("Db-Library not intialized.");
    return;
    }
    //get selected item
    int nIndex = m_ImageList.GetCurSel();
    if(nIndex == LB_ERR)
    {
    AfxMessageBox("Select a item first");
    return;
    }
    char* id = (char*)m_ImageList.GetItemDataPtr(nIndex);
    //get file name
    strcpy(szPath, "C:\\temp\\");
    m_ImageList.GetText(nIndex, szPath + strlen(szPath));

    //Query database
    dbfcmd(m_pDbProc, "SELECT ImageBody FROM testimage WHERE ImageID = '%s'", id);
    if(dbsqlexec(m_pDbProc) == FAIL)
    {
    AfxMessageBox("Query Failed!");
    dbcancel(m_pDbProc);
    return;
    }
    if(dbresults(m_pDbProc) != SUCCEED)
    {
    AfxMessageBox("Get results failed!");
    dbcancel(m_pDbProc);
    return;
    }
    DBINT r;
    FILE* fp = fopen(szPath, "wb");
    while(1)
    {
    r = dbreadtext(m_pDbProc, pBuffer, BUFFERSIZE);
    if(r == NO_MORE_ROWS)
    break;
    else if(r == 0)
    continue;
    else if(r == -1)
    {
    AfxMessageBox("Error in read image field!");
    dbcancel(m_pDbProc);
    fclose(fp);
    return;
    }
    else
    fwrite(pBuffer, sizeof(char), r, fp);
    }
    if(dbresults(m_pDbProc) == FAIL)
    {
    AfxMessageBox("Error in get results!");
    dbcancel(m_pDbProc);
    fclose(fp);
    return;
    }
    dbcancel(m_pDbProc);
    fclose(fp);
    }
      

  2.   

    http://expert.csdn.net/Expert/topic/1351/1351115.xml?temp=2.265567E-02
      

  3.   

    思路可以将整个文件以BYTE流存进数据库。
    #import "C:\Program Files\Common Files\SYSTEM\ADO\Msado15.dll" no_namespace rename("EOF","adoEOF")
    inline void TESTHR(HRESULT x) {if(FAILED(x)) _com_issue_error(x);} if(FAILED(::CoInitialize(NULL)))
    {
    MessageBox("ADO Init failed");
    return false;
    } _ConnectionPtr pConn= NULL; try
    {
    TESTHR(m_pConn.CreateInstance(__uuidof(Connection)));
            _bstr_t conn = "Provider = Microsoft.Jet.OLEDB.4.0;Data Source = H:\\record.mdb";
    //_bstr_t conn="DSN=test12";
    TESTHR(m_pConn->put_Mode(adModeReadWrite));
    m_pConn->Open(conn,"","",-1);
    }
    catch (_com_error& e)
    {
            AfxMessageBox(e.ErrorMessage(),MB_OK | MB_ICONERROR);
    return false;
    }读///
    sql.Format("select * from %s",TableName);

    try{
    _RecordsetPtr pRst;
    _variant_t vNULL;
    vNULL.vt = VT_ERROR;
    vNULL.scode = DISP_E_PARAMNOTFOUND; TESTHR(pRst.CreateInstance((__uuidof(Recordset))));
    pRst->PutRefActiveConnection(m_pConn);
    TESTHR(pRst->Open(_variant_t(_bstr_t(sql)),vNULL,adOpenForwardOnly,adLockOptimistic,adCmdText));

    if(!pRst->GetadoEOF()) 
    {

    CFile f;
    CString ff;
    ff.Format("d:\\temp\tmp.doc",TableName,i);
    f.Open(ff,CFile::modeWrite|CFile::modeCreate);
    long lPhotoSize = pRst->Fields->Item["nname"]->ActualSize;  
    long lIsRead=0;
    _variant_t varChunk;
    BYTE buf[ChunkSize];
    while(lPhotoSize>0)
    {
    lIsRead=lPhotoSize>=ChunkSize? ChunkSize:lPhotoSize;
    varChunk = pRst->Fields->
    Item["nname"]->GetChunk(lIsRead);
    for(long index=0;index<lIsRead;index++)         
    {           
    ::SafeArrayGetElement(varChunk.parray,&index,buf+index);   
    }
    f.Write(buf,lIsRead);
    lPhotoSize-=lIsRead;
    }//while()
    f.Close();
    }
    pRst->Close();
    }
    catch (_com_error& e)
    {
             CString str=(char*)e.Description();
    str = str+"\n  "+e.ErrorMessage();
    ::MessageBox(NULL,str,"错误",MB_OK | MB_ICONERROR);
    return false;
    }写/////////////
      try
    {        CString sql;
    sql.Format("select * from %s",TableName);

    _RecordsetPtr pRst;
    _variant_t vNULL;
    vNULL.vt = VT_ERROR;
    vNULL.scode = DISP_E_PARAMNOTFOUND; TESTHR(pRst.CreateInstance((__uuidof(Recordset))));
    pRst->PutRefActiveConnection(m_pConn);
    TESTHR(pRst->Open(_variant_t(_bstr_t(sql)),vNULL,adOpenForwardOnly,adLockOptimistic,adCmdText));

    VARIANT varChunk;
    SAFEARRAY *psa;
    SAFEARRAYBOUND rgsabound[1];

    //VT_ARRAY | VT_UI1 CFile f(fname,CFile::modeRead);
    BYTE  bVal[ChunkSize+1]; CFile ff(" word文件名",CFile::modeRead);
    //Create a safe array to store the array of BYTES  
    while(1)
    {
    uIsRead=ff.Read(bVal,ChunkSize);
    if(uIsRead==0)break;
    rgsabound[0].cElements =uIsRead;
    rgsabound[0].lLbound = 0;
    psa = SafeArrayCreate(VT_UI1,1,rgsabound);

    for(long index=0;unsigned(index)<uIsRead;index++)          
    {
    if(FAILED(SafeArrayPutElement(psa,&index,&bVal[index])))
    ::MessageBox(NULL,"ERROR","提示",MB_OK | MB_ICONWARNING);
    }

    varChunk.vt = VT_ARRAY|VT_UI1;
    varChunk.parray = psa; pRst->Fields->GetItem("nname")->AppendChunk(varChunk);  ::VariantClear(&varChunk);
    ::SafeArrayDestroyData( psa);
    if(uIsRead<ChunkSize)break;
    }//while(1)  
    ff.Close(); pRst->Update();
    pConn->Close();
    }
    catch (_com_error& e)
    {
             CString str=(char*)e.Description();
    str = str+"\n  "+e.ErrorMessage();
    ::MessageBox(NULL,str,"错误",MB_OK | MB_ICONERROR);
    m_pConn->RollbackTrans();
    return false;
    }
        m_pConn->CommitTrans();
      

  4.   

    直接操作word的文件可能比较费劲 因为格式比较复杂
    所以建议你把word文件在sql的字段中设置为image 就是一个可变长的二进制流
    具体的储存细节你可以看
    http://www.vckbase.com/document/viewdoc.asp?id=252
    写的很详细
      

  5.   

    读写,修改,保存时 读写数据库Blob字段到临时word文件。然后使用ole连接进程序。直接操作修改。跟在word 中操作一样的。
      

  6.   

    我看了
    http://www.csdn.net/Develop/Read_Article.asp?Id=10570
    但里面说:"给COfficeCntrItem添加一方法。GetIDispatch()"
    我照做了,如下:
    CString COfficeCntrItem::GetIDispatch()
    {
    ......
    }
    方法里有返回值,程序提示我ambiguous call to overloaded function
    这是什么原因,是不是这里不能用CString,那我应该用什么?
      

  7.   

    to: Saimen(★天大地大※何处是我家★)
    你什么意思?如果你还算个高手的话,应该是帮我想想办法,而不是挖苦我,我知道以我自己的能力解决不了问题,所以来这请教的
      

  8.   

    关于你说的问题我也说不清楚你可以去看一本《VISUAL C++ 高级界面编程》其中有四章是讲如果用 VC 操作 WORD如果我的书名没有记错的话还有一个问题就是如何在数据库中存入和读取 BIN 数据的问题了,你把WORD对象数据整个存入到数据库中去,就类似于存图像到数据库中去。你最快的办法不是问,是查, SEARCH 原来的文档问题,在 VCKBASE  VCHELP VCCODE 几个中文站点去找,在这里问是不可能 24 小时有一点头绪的----------------------------------------------------------------
    原贴内容:
    不好意思,见谅了,这几天这些东西搞得我心情不太好,24小时内我找到解决的办法就好说,如果找不到的话我真没法和客户交待了!
      

  9.   

    http://support.microsoft.com/default.aspx?scid=kb;zh-cn;316207
    也许能帮你。以前我写了一个程序,隐藏的打开word,然后用它做这些事情。
      

  10.   

    用VC控制WORD的代码现在已经没有问题,现在我的问题在于怎样才能利用这段代码连接并控制SQL200数据库的IMAGE字段,达到对数据库字段的读取,修改,保存。另外,用该程序生成的WORD文档利用WORD2000打开的时候为什么是乱码?而该程序为什么不能打开已有的WORD文档?请大家指点!如果有斑竹载的话,请把改贴置顶好么,我相信如果达到预期效果的话者部分内容对大家都有用的!谢谢了!
      

  11.   

    楼主:
        给你点小建议,
          你可以把整个Word文件作为数据表中一个长二进制数据保存,在需要编辑,访问该文件的时候,再从数据库中读出并生成该文件,利用自动化控制Word,打开该文件。结束操作后,再把文件写回数据库。删除该文件